zoukankan      html  css  js  c++  java
  • 利用btrace工具监控在线运行java程序

    
    一、作用
    可以用于对运行中java程序进行诊断监控分析,也可以用于开发阶段查看一些异常信息或者调用过程(如有些第三方代码没有源代码,不便于debug调试)。
    注:如果用于对在线运行系统的诊断,需要十分谨慎。
    1.脚本编写是否准确无法
    2.监测范围是否可控,不能监控过大的范围,给系统带来大的冲击
    3.使用btrace工具,会占用一部分内存,如果当前程序内存空间已经不够用了,则不能使用,若强行使用,可能会导致java内存不足而从引起java虚拟机退出
    4.通过实际测试,监控不能保证每次都正确监控到结果,而且有时可能会无法正常退出监控。这种方式只能作为定位线上问题的最后一招。
    典型应用场景:
    1. 监控应用从数据库连接池获取和释放连接(用于发现连接未关闭情况)
    2. 监控应用程序所有数据库操作对应的SQL语句
    3. 监控指定方法执行耗时
    4. 监控线程的启动和终止
    5. 监控对象的创建
    6. 捕获并打印所有异常信息(对于程序中未在日志中打印出来的信息可以通过这种方式捕获到)
    7. 监控多线程环境下,资源的竞争情况,对synchronized修饰的方法及代码块进行监控
    8. 检测死锁(当然还有其他方法,如通过jstack pid方式直接获取线程堆栈信息即可查看是否有死锁)
    1. 建立存放btrace的目录,如d:/btrace
    2. 将btrace-bin.zip内容解压到此目录
    3. 在d:/btrace目录下,新建btrace_script目录,用于存放监控脚本(其实监控脚本放在哪里都是可以的)
    2)linux安装指导
    1. mkdir btrace
    2. 将btrace-bin.tar.gz上传到此目录
    3. tar -xvf btrace-bin.tar.gz
    4. cd bin
    5. chmod 755 *
    6. 在btrace目录下,mkdir trace_script,用于存放监控脚本

    3)运行指导

      1.Windows

        i.打开命令行窗口,切换至bin目录,执行:btrace.bat pid ../btrace_script/TraceTest.java  (其中pid为要监控的java进程的ID,可以通过jps命令查看正在运行的所有java进程的ID)

        ii.退出时按Contrl+c,再按1

      2.Linux

        i.在bin目录下,执行:./btrace pid ../trace_script/TraceTest.java (其中pid为要监控的java进程的ID,可以通过jps命令查看正在运行的所有java进程的ID)

        ii.退出时按Contrl+c,再按1

     注:运行命令还可以补充其他的参数,[-I <include-path>] [-p <port>] [-cp <classpath>],详见btrace压缩包中docs/usersguide.html,其中-p参数用于指定btrace监听的端口,默认为2020,如果被其他程序占用了,则必须使用此参数指定其他的可用端口

    4)编写监控脚本指导

     新建一个普通的java工程,将btrace-bin.zip/build下3个jar包加入编译路径中,然后就可以进行监控脚本开发了。(所谓的监控脚本,也是普通的java程序,只是编译和执行方式不同于普通程序)

    四、针对典型场景的监控脚本

    1. 监控应用从数据库连接池获取和释放连接(用于发现连接未关闭情况)
    2. 监控应用程序所有数据库操作对应的SQL语句

    3. 监控指定方法执行耗时

    4. 监控线程的启动和终止

    5. 监控对象的创建,见Btrace自带样例NewComponent.java
    6. 捕获并打印所有异常信息(对于程序中未在日志中打印出来的信息可以通过这种方式捕获到),见Btrace自带样例OnThrow.java
    7. 监控多线程环境下,资源的竞争情况,对synchronized修饰的方法及代码块进行监控,见Btrace自带样例AllSync.java
    8. 检测死锁,见Btrace自带样例Deadlock.java

    五、常用函数说明

    1. 判断类型 instanceof
    2. 打印当前线程调用栈 BtraceUtils.Threads.jstack()
    3. 打印所有线程栈 BtraceUtils.Threads.jstackAll()
    4. 连接字符串 BtraceUtils.Strings.strcat
    5. 打印BtraceUtils.print/println
    6. 获取当前时间BtraceUtils.timestamp("yyyyMMddHHmmss)
    7. 整形转字符串 Strings.str()
    8. 获取当前线程名 Threads.name(Threads.currentThread()) 
    9. 获取java运行环境系统属性 Sys.Env.property 等同于System.getProperty
    10. 获取对象类名 Reflective.name(Reflective.classOf(obj)
    11. 取对象属性值
       方式1:
    函数参数中直接引用参数类
    Field field = Reflective.field("cn.jerry.User","name");
    print(Reflective.get(field,user);

    如果需要访问其他自定义的类,可以通过在执行btrace时增加参数[-cp <classpath>]来指定类访问路径
      方式2:
    函数参数中不指定具体参数,使用AnyType[] args,在函数体内使用如下方式获取:
    Field field = Reflective.field("cn.jerry.User","name");
    print(Reflective.get(field,args[0]);


    参考资料:

    BTrace简介:http://blog.csdn.net/mgoann/article/details/7268508

    原理研究:http://www.iteye.com/topic/1005918

    源代码:kenai.com/projects/btrace/sources/hg/show

  • 相关阅读:
    手机号码正则表达式
    POJ 3233 Matrix Power Series 矩阵快速幂
    UVA 11468
    UVA 1449
    HDU 2896 病毒侵袭 AC自动机
    HDU 3065 病毒侵袭持续中 AC自动机
    HDU 2222 Keywords Search AC自动机
    POJ 3461 Oulipo KMP模板题
    POJ 1226 Substrings KMP
    UVA 1455 Kingdom 线段树+并查集
  • 原文地址:https://www.cnblogs.com/jerry1999/p/4175930.html
Copyright © 2011-2022 走看看