`
jamie.wang
  • 浏览: 344829 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

用BTrace排查性能问题

    博客分类:
  • Java
阅读更多

BTrace是一个可以动态跟踪Java代码执行的工具,网上已经有很多文章介绍,我这里分享一个我在实际工作中排查性能问题的例子。

现象

我的一个REST接口调用非常慢,postman耗时3873 ms,这个接口就是从redis里把一批数据取出来,redis性能很好,理论上不会这么慢,于是用btrace,trace方法调用。

 

/* BTrace Script Template */
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class TracingScript {
    /* put your code here */
    @TLS  
    private static long startlTime = 0;
    @TLS  
    private static long startmTime = 0;

    @TLS  
    private static long startjTime = 0;
    @TLS  
    private static long startrTime = 0;
    @TLS  
    private static long startbTime = 0;

    @OnMethod(clazz="com.xx.monitoring.api.util.JedisHelper", method="listSize")
    public static void startjMethod() {
        startjTime = timeMillis();
    }

    @OnMethod(clazz="com.xx.monitoring.api.util.JedisHelper", method="listSize", location=@Location(Kind.RETURN))
    public static void endjMethod() {
        println(strcat("listSize method execute time=>", str(timeMillis()-startjTime)));  
        println("-------------------------------------------");  
    }

    @OnMethod(clazz="com.xx.monitoring.api.util.JedisHelper", method="listRange")
    public static void startrMethod() {
        startrTime = timeMillis();
    }

    @OnMethod(clazz="com.xx.monitoring.api.util.JedisHelper", method="listRange", location=@Location(Kind.RETURN))
    public static void endrMethod() {
        println(strcat("listRange method execute time=>", str(timeMillis()-startrTime)));  
        println("-------------------------------------------");  
    }

    @OnMethod(clazz="com.xx.monitoring.api.persistence.MetricRedisDao", method="listMetricByIds")
    public static void startbMethod() {
        startbTime = timeMillis();
    }

    @OnMethod(clazz="com.xx.monitoring.api.persistence.MetricRedisDao", method="listMetricByIds", location=@Location(Kind.RETURN))
    public static void endbMethod(java.util.List metricIds) {
        println("metrcIds.size: " + metricIds.size());
        println(strcat("listMetricByIds method execute time=>", str(timeMillis()-startbTime)));  
        println("-------------------------------------------");  
    }

    @OnMethod(clazz="com.xx.monitoring.api.service.MetricServiceImpl", method="listMetricsInternal")
    public static void startlMethod() {
        startlTime = timeMillis();
    }

    @OnMethod(clazz="com.xx.monitoring.api.service.MetricServiceImpl", method="listMetricsInternal", location=@Location(Kind.RETURN))
    public static void endlMethod() {
        println(strcat("listMetricsInternal method execute time=>", str(timeMillis()-startlTime)));  
        println("-------------------------------------------");  
    }

    @OnMethod(clazz="com.xx.monitoring.api.service.MetricServiceImpl", method="listMetricsMap")
    public static void startmMethod() {
        startmTime = timeMillis();
    }

    @OnMethod(clazz="com.xx.monitoring.api.service.MetricServiceImpl", method="listMetricsMap", location=@Location(Kind.RETURN))
    public static void endmMethod() {
        println(strcat("listMetricsMap execute time=>", str(timeMillis()-startmTime)));  
        println("-------------------------------------------");  
    }
}

 编译:

 

$ btracec TracingScript.java

开始trace

$ btrace  19416 TracingScript.class

结果:

 

DEBUG: received com.sun.btrace.comm.MessageCommand@5b6f7412
listSize method execute time=>3
DEBUG: received com.sun.btrace.comm.MessageCommand@27973e9b
-------------------------------------------
DEBUG: received com.sun.btrace.comm.MessageCommand@312b1dae
listRange method execute time=>18
DEBUG: received com.sun.btrace.comm.MessageCommand@7530d0a
-------------------------------------------
DEBUG: received com.sun.btrace.comm.MessageCommand@27bc2616
listRange method execute time=>19
DEBUG: received com.sun.btrace.comm.MessageCommand@3941a79c
-------------------------------------------
DEBUG: received com.sun.btrace.comm.MessageCommand@506e1b77
listMetricsInternal method execute time=>4820
DEBUG: received com.sun.btrace.comm.MessageCommand@4fca772d
-------------------------------------------
DEBUG: received com.sun.btrace.comm.MessageCommand@9807454
listMetricsMap execute time=>4821

 可以看到listMetricsInternal执行了4820毫秒

这个方法就是把metric的id循环从redis取metric bean,初步判断是id太多导致很慢,继续trace

添加方法:

 

    @OnMethod(clazz="com.xx.monitoring.api.persistence.MetricRedisDao", method="listMetricByIds", location=@Location(Kind.RETURN))
    void endbMethod(java.util.List<String> metricIds) {
        println("metrcIds.size: " + str(metricIds));
        println("-------------------------------------------");  
    }

 执行结果:

 

 

metrcIds.size: [weblogic.datasource.waiting_for_connection_high_count, weblogic.datasource.leaked_connection_count, weblogic.datasource.active_connections_currentCount, weblogic.threadpool.standby_thread_count, weblogic.threadpool.active_thread_idle_count, weblogic.threadpool.execute_thread_total_count, weblogic.session.open_sessions_current_count, weblogic.session.open_sessions_high_count, weblogic.session.sessions_opened_total_count, weblogic.server.health_state, weblogic.server.activation_time, server.os.kernel_version, server.os.version, server.os.id, server.interfaces.tx, server.interfaces.rx, server.disk.used_percent, server.cpu.load, server.memory.free_percent, server.memory.used_percent, server.cpu.idle, server.cpu.iowait, server.cpu.sys, server.cpu.user, oracle.info.status, oracle.worst.sql, oracle.time_ratio.cpu_time_ratio, oracle.time_ratio.wait_time_ratio, oracle.connection.count, jvm.memory.used, jvm.memory.max, jvm.memory.committed, jvm.thread.total_started_thread_count, jvm.thread.daemon_thread_count, jvm.thread.peak_thread_count, jvm.thread.count, jvm.gc.collection_time, jvm.gc.collection_count, jvm.classsloading.unloaded_class_count, jvm.classsloading.loaded_class_count, jvm.classsloading.total_loaded_class_count, jvm.info.input_arguments, jvm.info.vm_id, jvm.info.vm_version, weblogic.datasource.waiting_for_connection_high_count, weblogic.datasource.leaked_connection_count, weblogic.datasource.active_connections_currentCount, weblogic.threadpool.standby_thread_count, weblogic.threadpool.active_thread_idle_count, weblogic.threadpool.execute_thread_total_count, weblogic.session.open_sessions_current_count, weblogic.session.open_sessions_high_count, weblogic.session.sessions_opened_total_count, weblogic.server.health_state, weblogic.server.activation_time, server.os.kernel_version, server.os.version, serve



还有很多
...

一共3610个,从redis取一个1ms,那也要3610ms,怪不得。

 

原因找到了,改代码就很简单了

另外发现BTrace还有一个工具专门分析性能的BTraceUtils.Profiling,代码:

 

import com.sun.btrace.BTraceUtils;
import com.sun.btrace.Profiler;
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;


@BTrace class Profiling {
    @Property
    Profiler swingProfiler = BTraceUtils.Profiling.newProfiler();
    
    @OnMethod(clazz="/com\\.xx\\.monitoring\\.api\\..*/", method="/.*/")
    void entry(@ProbeMethodName(fqn=false) String probeMethod) { //fqn是否打印长方法名
        BTraceUtils.Profiling.recordEntry(swingProfiler, probeMethod);
    }
    
    @OnMethod(clazz="/com\\.xx\\.monitoring\\.api\\..*/", method="/.*/", location=@Location(value=Kind.RETURN))
    void exit(@ProbeMethodName(fqn=false) String probeMethod, @Duration long duration) { 
        BTraceUtils.Profiling.recordExit(swingProfiler, probeMethod, duration);
    }
    
    @OnTimer(5000) //每5秒打印一次
    void timer() {
        BTraceUtils.Profiling.printSnapshot("Performance profile", swingProfiler);
    }
}

 结果:

 

 

Performance profile
  Block                Invocations  SelfTime.Total  SelfTime.Avg  SelfTime.Min  SelfTime.Max  WallTime.Total  WallTime.Avg  WallTime.Min  WallTime.Max
  preHandle                      1           96000         96000         96000         96000           96000         96000         96000         96000
  listSize                       1         2231000       2231000       2231000       2231000         2231000       2231000       2231000       2231000
  listRange                      2        18447000       9223500         23000      18424000        36871000      18435500      18424000      18447000
  getMetric                   3610        20915000          5793          1000        384000      3805159000       1054060        689000       5752000
  getMetricIndexOfId          3610       189140000         52393         19000        930000       189140000         52393         19000        930000
  get                         3610      3583769000        992733        629000       4758000      3595104000        995873        633000       4787000
  <init>                      3610          760000           210             0         10000          760000           210             0         10000
  setId                       3610         1983000           549             0         20000         1983000           549             0         20000
  setUnit                     3610         2019000           559             0         51000         2019000           559             0         51000
  setCreated                  3610         2111000           584             0         32000         2111000           584             0         32000
  setUpdated                  3610         1556000           431             0         26000         1556000           431             0         26000
  setValueType                3610         1251000           346             0         19000         1251000           346             0         19000
  setDisplayName              3610         1476000           408             0         54000         1476000           408             0         54000
  setCustomized                271          179000           660             0         16000          179000           660             0         16000
  doFilter                       1        22833000      22833000      22833000      22833000      3867649000    3867649000    3867649000    3867649000
  listMetricsMap                 2         2151000       1075500         49000       2102000      7685645000    3842822500    3842798000    3842847000
  listMetricsInternal            1           13000         13000         13000         13000      3839969000    3839969000    3839969000    3839969000
  listMetrics                    1         2332000       2332000       2332000       2332000      3839956000    3839956000    3839956000    3839956000
  listMetricByIds                1        11787000      11787000      11787000      11787000      3816946000    3816946000    3816946000    3816946000
  getId                       3676          737000           200             0         12000          737000           200             0         12000
  isCustomized                  66           11000           166             0          1000           11000           166             0          1000
  getUnit                       66            8000           121             0          1000            8000           121             0          1000
  getCreated                    66            9000           136             0          1000            9000           136             0          1000
  getUpdated                    66            9000           136             0          1000            9000           136             0          1000
  getValueType                  66           14000           212             0          1000           14000           212             0          1000
  getDisplayName                66            9000           136             0          1000            9000           136             0          1000
  postHandle                     1         1803000       1803000       1803000       1803000         1803000       1803000       1803000       1803000

 可见getMetric执行了3610次

 

怎么样,BTrace还是很强大的吧,分析线上问题很方便

 

 

 

 
 
分享到:
评论
1 楼 仰望摩天轮 2016-08-09  
大神 用webloginc或者websphere容器的时候 jps抄不到pid 这种情况 你知道是咋用btrace的么 请教了

相关推荐

    java在线问题排查利器之Btrace&Greys1

    总结来说,Btrace和Greys是Java开发者在生产环境中排查问题的有力助手,它们能够帮助我们实时查看代码执行情况,定位性能问题,且无需改动源代码或重启服务。通过熟练掌握这类工具,可以极大地提高问题解决的效率,...

    jvisualvm btrace插件离线安装

    而BTrace则是Oracle公司推出的一个开源项目,允许开发者在运行时对Java应用进行安全的动态代码插入,用于性能监控、故障排查等。 当网络环境不稳定或者无法访问互联网时,我们就需要离线安装BTrace插件。离线安装的...

    BTrace监控远程服务器使用实例

    **BTrace监控远程服务器使用实例** BTrace 是一个强大的、安全的、动态的Java...通过熟练掌握BTrace的使用,可以有效地提升故障排查效率,优化Java应用的性能。记住,合理配置安全策略和权限,确保远程监控的安全性。

    BTrace-一个用于Java平台的安全动态的跟踪工具

    BTrace将这种能力引入到了Java世界,使得开发者可以对Java应用程序进行细粒度的性能分析和故障排查。通过BTrace,我们可以追踪方法调用、监控对象创建、检测锁竞争等关键操作,这对于性能优化和问题定位来说极其宝贵...

    btrace安装包

    BTrace是一款强大的Java诊断工具,专用于实时、安全地进行生产环境中的应用程序性能监控和故障排查。它的核心特性在于能够在不中断程序运行的情况下,动态插入代码进行跟踪和分析,这对于理解复杂的系统行为和定位...

    btrace1.3.9

    【标题】"btrace1.3.9"指的是BTrace工具的一个特定版本,1.3.9,这是一款强大的Java应用程序动态跟踪工具。BTrace利用Java的JVMTI(Java ...无论是对于排查问题还是进行性能优化,BTrace都是一种强大的辅助工具。

    btrace.jar

    在日常的调试维护中,虽然btrace提供了一种非常便利的手段,但我们仍然提倡首先利用日志系统进行问题排查。日志记录了程序运行过程中的详细信息,可以帮助我们理解程序的运行状态,定位错误来源。而btrace则更适用于...

    Btrace资源

    2. 虽然Btrace可以无侵入地跟踪应用程序,但过度使用可能会对性能产生影响,因此应在生产环境谨慎使用。 3. Btrace与特定的JDK版本兼容,本资源包特别提到支持JDK 11。 总的来说,Btrace是一个强大的Java调试和监控...

    btrace_extend-master

    BTrace工具通常被系统管理员和性能工程师用来找出性能瓶颈,或者在复杂的问题排查过程中收集必要的运行时信息。 【详细说明】BTrace的核心功能包括: 1. **动态探查**:BTrace可以在运行时向Java应用添加探查代码...

    btrace支持jdk1.7 linux下使用

    此工具在Java 1.5及更高版本上运行,特别地,这里提到的是它在JDK 1.7环境下同样兼容,这意味着开发者可以在Linux系统中利用BTrace对基于JDK 1.7的应用进行实时监控和问题排查。 1. **BTrace原理**: BTrace通过...

    btrace-bin.zip

    5. **广泛的应用**:BTrace适用于各种线上问题的排查,包括性能瓶颈定位、内存泄漏检测、线程状态分析等。 【压缩包内容解析】 - **COPYRIGHT**:通常包含软件的版权信息和使用许可条款,对于BTrace这样的开源软件...

    btrace-bin-1.3.11.tgz.tar.gz

    "samples"目录则提供了一些示例,方便用户学习如何使用BTrace进行性能分析和问题定位。 核心部分在于"bin"目录,这里包含了可执行的BTrace命令行工具。通过这些二进制文件,用户可以在Java应用程序运行时动态插入...

    btrace调试工具

    总结,BTrace作为一款强大的Java在线调试工具,通过字节码增强技术实现了对运行中的Java应用的实时监控,对于开发人员而言,是进行性能优化和问题排查的得力助手。合理运用BTrace,可以极大地提升线上问题解决的效率...

    BTrace自我总结测试代码

    在上述测试中,通过监控`List`参数和自定义对象,可以帮助理解程序运行时的数据流动和对象状态,对于问题排查和优化非常有价值。 通过深入理解和实践BTrace,开发者可以更有效地诊断和优化Java应用程序,提升系统的...

    Btrace 学习1

    博文链接:https://tristan-s.iteye.com/blog/1960257 提供了关于 BTrace 使用和理解的详细教程,可以帮助读者更深入地了解如何利用 BTrace 进行问题排查和性能优化。 【标签】:“源码”、“工具” 【知识点详解...

    BTrace测试

    BTrace的全称是"Berkeley Trace",它基于字节码注入技术,可以实时地、安全地在运行中的Java应用程序上添加监控脚本,帮助我们理解程序的运行状态,定位问题,优化性能。 BTrace的工作原理主要是通过ASM库来动态...

    btrace支持jdk1.6上运行的版本

    **BTrace:深入理解与应用** BTrace 是一个强大的动态代码跟踪工具,它允许开发者在运行时对Java应用程序进行安全的、低开销的...无论是在排查问题、优化代码还是理解复杂系统的行为,BTrace 都是一个不可或缺的工具。

    btrace源代码

    它允许开发者在运行时对Java应用程序进行性能分析和故障排查,而无需修改或重启应用。BTrace通过其独特的字节码注入技术,为开发者提供了对应用程序的细粒度监控能力。本文将基于提供的"Btrace源代码"进行深入探讨,...

    btrace引导文件安装Btrace

    **Btrace 概述** ...结合VisualVM插件,我们可以更直观地管理和分析监控数据,这对于调试、性能优化以及问题排查具有极大的价值。理解Btrace的工作原理和使用方法,对于提升Java开发和运维效率非常有帮助。

    btrace-bin-1.3.9.tgz

    通过BTrace,开发者能够深入理解程序的运行状态,定位性能瓶颈,诊断并发问题,以及实施细粒度的日志记录,从而提升应用的性能和稳定性。结合提供的文档和示例,用户可以逐步掌握这个强大的工具,实现高效的问题排查...

Global site tag (gtag.js) - Google Analytics