系列文章
- 「BTrace」基本概念和初步介绍(1)
- 「BTrace」安装介绍和使用原理(2)- 未完成
- 「BTrace」实战代码进行调试使用(3)- 未完成
- 「BTrace」运行时异常原因分析(4)- 未完成
背景说明(痛点分析)
- 线上遇到了问题?
- 服务上线出问题,想增加打印日志怎么办?
- 线上怀疑某个接口慢,想打印接口耗时怎么办?
- 线上某个接口报错,想看看调用的参数和谁调用了怎么办?
- 线上出错了,想看某个对象的数据怎么办?
- 线上出错了,想看一下jvm的一些信息怎么办?
- 不确定线上某一行代码执行了怎么办?
传统解决方案
- 修改源代码 -> 增加相关打印日志 -> hotswap(热加载+热刷新)
- Thread.dumpStack():打印输出当前的堆中信息数据
- beanshell可以查看内存数据
- jvm信息可以通过jvm内置命令去获取:主要的办法就是jstack到处线程堆中信息
缺点
- 代码侵入式
- 不灵活
- 源代码冗余
- 如果你的服务不支持hotswap呢?
BTrace应用场景
- 服务慢,能找出慢在哪一步,哪个函数里么?
- 谁调用了System.gc(),调用栈如何?
- 谁构造了一个超大的ArrayList?
- 入参或对象属性,导致抛出了这个异常?进入了这个处理分支?
- 针对没有异常堆栈的情况,可以将异常实时输出。
BTrace基本介绍
Btrace是SUN公司开发的一款动态的Trace工具,是Java的安全可靠的动态跟踪工具。他的工作原理是通过
instrument + asm
来对正在运行的java程序中的class类进行动态增强。说他是安全可靠的,是因为它对正在运行的程序是只读的。也就是说,他可以插入跟踪语句来检测和分析运行中的程序,不允许对其进行修改。
BTrace开源地址
Btrace最大的好处是可以自己编写脚本,可以实时应用的调用信息,而不用频繁的重启系统。Btrace目前托管在Github上BTrace-Github官方地址,BTrace官方文档。可以学习研究下。
BTrace限制条件
因此他存在一些限制:
- 不能创建对象
- 不能创建数组
- 不能抛出和捕获异常
- 不能调用任何对象方法和静态方法
- 不能给目标程序中的类静态属性和对象的属性进行赋值
- 不能有外部、内部和嵌套类
- 不能有同步块和同步方法
- 不能有循环(for, while, do..while)
- 不能继承任何的类
- 不能实现接口
- 不能包含assert断言语句
这些限制其实是可以使用unsafe模式绕过。通过声明 @BTrace(unsafe = true) annotation并且以unsafe模式-u运行btrace
实际使用非安全模式跟踪时,发现一个问题,一个进程如果被安全模式btrace探测过一次, 后面再使用非安全模式进行探测时非安全模式不生效。
BTrace基本原理
总体来说,BTrace是基于动态字节码修改技术(Hotswap)来实现运行时 java 程序的跟踪和替换。
大体的原理可以用下面的公式描述:
Client(Java compile api + attach api) + Agent(脚本解析引擎 + ASM + JDK6 Instumentation) + Socket
其实BTrace就是使用了
java attach api
附加agent.jar,然后使用脚本解析引擎+asm来重写指定类的字节码,再使用instrument实现对原有类的替换。
BTrace注意事项
合理利用Btrace确实会给线上定位问题提速不少,但是也要谨慎,尽量的将范围缩小,在执行Btrace脚本之前,先到测试环境测试一下,不然有可能让jvm奔溃。所以编写脚本的时候最好还是利用IDE来编写代码。
BTrace最后总结
BTrace是检查和解决线上的问题的杀器,BTrace可以通过编写脚本的方式,获取程序执行过程中的一切信息,并且,注意了,不用重启服务,是的,不用重启服务。写好脚本,直接用命令执行即可,不用动原程序的代码。