线上性能检测工具之Btrace


当系统运行后,有的方法的执行时间让人不满意,需要用一些工具去查看执行的情况,可以考虑使用Btrace,使用还是比较简单的。

1、安装

首先到网上下个Btrace包吧,官方网址是:http://kenai.com/projects/btrace

解压后,把bin目录加入到环境变量中就可以使用了。

2、验证

配置环境变量后,打开一个CMD控制台:

输入命令 btrace:

Microsoft Windows [版本 6.1.7601]

版权所有 (c) 2009 MicrosoftCorporation。保留所有权利。

 

C:\Users\fan>btrace

Usage: btrace <options> <pid> <btrace source or .classfile> <btrace arguments>

where possible options include:

  -classpath <path> Specifywhere to find user class files and annotation processors

  -cp <path>        Specify where to find user class filesand annotation processors

  -I <path>        Specify where to find include files

  -p <port>        Specify port to which the btrace agentlistens for clients

 

配置就完成了。

3、开发

btrace安装好了,可以到btrace的官方帮助文档中去看语法http://kenai.com/projects/btrace/pages/UserGuide

 

写btrace脚本和一般的java差别不大,只是用了一些annotation来标识某个类是跟踪脚本。btrace用到的jar包基本都在下载的/btrace-bin/build文件下,将这三个包导进工程就可以使用了。【btrace脚本写好后可以不用编译,直接执行.java文件就可以】

 

看一个trace的例子。

package com.btrace;

 

import java.util.Random;

import java.util.Arrays;

/**

 * 简单的Btrace查看的示例,主要是方法的运行时间和内存使用

 * @author 范芳铭

 */

public class EasyBtraceTest {

      private Object[] elements;

      private int size = 0;

      private static final intDEFAULT_INI_CAPACITY = 16;

     

      public byte[] placeHolder =new byte[64 * 1024]; //占位符

      public EasyBtraceTest(){

              elements = new Object[DEFAULT_INI_CAPACITY];

      }

     

      public static voidmain(String[] args) throws Exception {

              while (true) {

                    Random random =new Random();

                    execute(random.nextInt(4000));

              }

 

      }

 

      public static Integerexecute(int sleepTime) {

              try {

                    Thread.sleep(sleepTime);

                    if (sleepTime %2 == 0){

                            System.out.println("正在执行");

                            EasyBtraceTesttest = new EasyBtraceTest();

                            test.push(test);

                    }

              } catch (Exception e) {

              }

              System.out.println("sleeptime is=>" + sleepTime);

              return 0;

      }

     

      //用于占用内存

      public void push(Object e){

              if (elements.length ==size )

                    elements=Arrays.copyOf(elements, 2 * size + 1 );

              elements[size++] = e;

      }

}

4、btrace脚本

我要监控execute方法执行的时间,以及使用的内存的情况

 

 btrace脚本如下:

package com.btrace;

 

import static com.sun.btrace.BTraceUtils.println; 

import static com.sun.btrace.BTraceUtils.str; 

import static com.sun.btrace.BTraceUtils.strcat; 

import static com.sun.btrace.BTraceUtils.timeMillis; 

 

import com.sun.btrace.BTraceUtils.Sys;

import com.sun.btrace.annotations.BTrace;

import com.sun.btrace.annotations.Kind;

import com.sun.btrace.annotations.Location; 

import com.sun.btrace.annotations.OnMethod; 

import com.sun.btrace.annotations.OnTimer;

import com.sun.btrace.annotations.ProbeClassName; 

import com.sun.btrace.annotations.ProbeMethodName; 

import com.sun.btrace.annotations.TLS;

@BTrace 

public class TraceEasyBtrace { 

     

    @TLS 

    private static long startTime =0; 

     

    @OnMethod(clazz ="com.btrace.EasyBtraceTest", method = "execute") 

    public static voidstartMethod(){ 

        startTime =timeMillis(); 

    } 

     

    @OnMethod(clazz ="com.btrace.EasyBtraceTest", method = "execute", location =@Location(Kind.RETURN)) 

    public static voidendMethod(){ 

        println(strcat("theclass method execute time=>", str(timeMillis()-startTime))); 

      println("-------------------------------------------"); 

    } 

     

    @OnMethod(clazz ="com.btrace.EasyBtraceTest", method = "execute", location =@Location(Kind.RETURN)) 

    public static voidtraceExecute(@ProbeClassName String name,@ProbeMethodName String method,intsleepTime){ 

        println(strcat("theclass name=>", name)); 

        println(strcat("the classmethod=>", method)); 

        println(strcat("theclass method params=>", str(sleepTime))); 

         

    } 

   

    @OnTimer(4000)

    public static void printMem() {

        println("Heap:");

      println(Sys.Memory.heapUsage());

      println("Non-Heap:");

      println(Sys.Memory.nonHeapUsage());

    }

上面源码有几点注意的:

1、 @BTrace 这个annotation表明这个类是btrace脚本,

2、@OnMethod(clazz = " com.btrace.EasyBtraceTest ",method = "execute")

中clazz标明要监控那个类,也可以用正则匹配的方式,method标明要监控类的哪个方法

 

5、运行和具体使用

代码写好了,将EasyBtraceTest程序跑起来,看到每个几秒控制台就会有信息输出:

sleep time is=>3774

sleep time is=>1883

sleep time is=>3863

….

说明程序已经在跑了。

用TraceEasyBtrace.java这个脚本来监控EasyBtraceTest

前提条件:

两个目录:

TraceEasyBtrace.java  所在的目录,在D:\develop\eclipse\work\performance\src\com\btrace下

JAVA的bin目录下,用JPS查看进程id(应用每次运行可能都会变动,要在本机运行)

我的目录在:

C:\Users\fan>cd C:\Program Files\Java\jdk1.6.0_25\bin

 

获得运行的JAVA的进程ID;

进入命令行:

Microsoft Windows [版本 6.1.7601]

版权所有 (c) 2009 MicrosoftCorporation。保留所有权利。

 

C:\Users\fan>cd C:\Program Files\Java\jdk1.6.0_25\bin

 

C:\Program Files\Java\jdk1.6.0_25\bin>jps

7364 EasyBtraceTest

2268

5392

6816 Jps

 

C:\Program Files\Java\jdk1.6.0_25\bin>

 

其中,7364 EasyBtraceTest 就是我们这个应用的PID。

这时候在TraceEasyBtrace.java 所在的目录下运行命令btrace 7364 TraceEasyBtrace.java,结果如下:

Microsoft Windows [版本 6.1.7601]

版权所有 (c) 2009 MicrosoftCorporation。保留所有权利。

 

C:\Users\fan>cd C:\Program Files\Java\jdk1.6.0_25\bin

 

C:\Program Files\Java\jdk1.6.0_25\bin>jps

7364 EasyBtraceTest

2268

5392

6816 Jps

 

C:\Program Files\Java\jdk1.6.0_25\bin>d:

 

D:\>cd D:\develop\eclipse\work\performance\src\com\btrace

 

D:\develop\eclipse\work\performance\src\com\btrace>btrace 7364TraceEasyBtrace.java

Heap:

init = 0(0K) used = 1005544(981K) committed = 5177344(5056K) max =66650112(65088K)

Non-Heap:

init = 12746752(12448K) used = 5666640(5533K) committed = 13303808(12992K)max = 100663296(98304K)

the class name=>com.btrace.EasyBtraceTest

the class method=>execute

the class method params=>3011

the class method execute time=>3012

-------------------------------------------

the class name=>com.btrace.EasyBtraceTest

the class method=>execute

the class method params=>2849

the class method execute time=>2850

 …

可以看到每当execute方法执行时,就会打印出一行信息。打印出了类名,方法名,参数,以及这个方法执行的时间。以及内存的使用情况;

这就是一个非常简单的btrace监控,还可以用于数据库执行语句的监控,多线程的监控,WebService的监控等。

本文永久更新链接地址:

相关内容