线上性能问题排查利器
背景
遇到性能问题,一般的排查手段包括查监控,查日志,本机调试,远程调试,灰度等,如果是只在线上环境出现,可能需要进行日志埋点,重新上线。
缺点1、需要上线。2、如果方法调用链很长,埋点可能不全。
BTrace
https://github.com/btraceio/btrace
Btrace (Byte Trace)是sun推出的一款Java 动态、安全追踪(监控)工具,可以在不停机的情况下监控系统运行情况,并且做到最少的侵入,占用最少的系统资源。。BTrace在使用上做了很多限制,如不能创建对象、不能使用数组、不能抛出或捕获异常、不能使用循环、不能使用synchronized关键字、脚本的属性和方法都必须使用static修饰等,具体限制条件可参考用户手册。根据官方声明,不当地使用BTrace可能导致JVM崩溃,如BTrace使用错误的.class文件,所以,可以先在本地验证BTrace脚本的正确性再使用
工具使用
安装
1、下载、解压
>sudo root
>wget https://github.com/btraceio/btrace/releases/download/v1.3.10.2/btrace-
bin-1.3.10.2.tgz
>mkdir btrace
>tar -zxvf btrace-bin-1.3.10.2.tgz -C btrace
2、配置变量JAVA_HOME,BTRACE_HOME
>vim .bash_profile
----
export JAVA_HOME=/usr/local/java
export BTRACE_HOME=~/btrace
export PATH=$PATH:$BTRACE_HOME/bin
---
>source .bash_profile
部署
ServiceMonitor.java
import com.sun.btrace.AnyType;
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
@BTrace
public class ServiceMonitor{
@OnMethod(clazz = "com.test.captcha.CaptchaFactory",method = "getCaptcha",location=@Location(Kind.RETURN))
public static void printMethodRunTime(int length, int level, @Return AnyType result ){
println( "length: " + length + " ,level: " + level);
println("result : " + result);
}
}
>jps -l
>btracec ServiceMonitor.java
>btrace ServiceMonitor
length: 4 ,level: 0
result : com.test.captcha.entity.ImageResult@4e57dac8
length: 4 ,level: 0
result : com.test.captcha.entity.ImageResult@5849ced6
length: 4 ,level: 0
常用方法注解
@OnMethod
方法执行时运行,@OnMethod(clazz=
clazz支持类全限定名、正则、带“+”前缀的类名(包含所有子类和接口实现),例如clazz = "com.test.captcha.CaptchaFactory",clazz="/javax\.swing\../",clazz="+java.util.logging.Logger"
method 方法名或正则
type返回类型,参数类型
location : Kind.ENTRY、Kind.RETURN、Kind.ERROR ,例如 location=@Location(value=Kind.RETURN, clazz="/./", method="/.*/")
@OnTimer
周期性执行 如@OnTimer(4000)
@OnError
用来指定当任何异常抛出时需要执行的操作。被该注解修饰后的BTrace函数会在同一个BTrace类的其他操作方法抛出异常时执行,
常用参数注解
@ProbeClassName
监听的类名
@ProbeMethodName
监听的方法名
@Return
将方法参数标记为包含返回值的参数
@Self
将参数标记为包含this示例的参数
@Duration
标记参数为方法持续时间值(ns),只适用于@OnMethod,并且需要配合Kind.ERROR或者Kind.RETURN使用
优点
无需修改原程序任何代码,无需重启直接使用
功能多,不仅能监控,还能直接修改线上应用代码,十分方便
缺点
退出后注入的字节码会一直保留,直到重启
使用不当可能会影响应用
为了避免对正常应用造成影响,有非常多的限制
- BTrace class不能新建类, 新建数组, 抛异常, 捕获异常,
- 不能调用实例方法以及静态方法(com.sun.btrace.BTraceUtils除外)
- 不能将目标程序和对象赋值给BTrace的实例和静态field
- 不能定义外部, 内部, 匿名, 本地类
- 不能有同步块和方法
- 不能有循环
- 不能实现接口, 不能扩展类
- 不能使用assert语句, 不能使用class字面值
TProflier
https://github.com/alibaba/TProfiler
TProfiler是一个可以在生产环境长期使用的性能分析工具.它同时支持剖析和采样两种方式,记录方法执行的时间和次数,生成方法热点 对象创建热点 线程状态分析等数据,为查找系统性能瓶颈提供数据支持. TProfiler在JVM启动时把时间采集程序注入到字节码中,整个过程无需修改应用源码.运行时会把数据写到日志文件,一般情况下每小时输出的日志小于50M.
业界同类开源产品都不是针对大型Web应用设计的,对性能消耗较大不能长期使用,TProfiler解决了这个问题.目前TProfiler已应用于淘宝的核心Java前端系统. 部署后低峰期对应用响应时间影响20% 高峰期对吞吐量大约有30%的降低(高峰期可以远程关闭此工具)
工具使用
打包
git clone [email protected]:alibaba/TProfiler.git
mvn assembly:assembly
生成TProfiler/pkg/TProfiler/lib/tprofiler-1.0.1.jar
配置
新增TProfiler.properties,没有则使用默认配置
#log file name
logFileName = tprofiler.log
methodFileName = tmethod.log
samplerFileName = tsampler.log
#basic configuration items
# 开始取样时间
startProfTime = 1:00:00
# 结束取样时间
endProfTime = 23:00:00
# 取样的时间长度
eachProfUseTime = 10
# 每次取样的时间间隔
eachProfIntervalTime = 1
samplerIntervalTime = 20
# 端口,主要不要冲突了
port = 50000
debugMode = false
needNanoTime = false
# 是否忽略 get set 方法
ignoreGetSetMethod = true
#file paths 日志路径
logFilePath = /data/applogs/tprofile/${logFileName}
methodFilePath =/data/applogs/tprofile/${methodFileName}
samplerFilePath =/data/applogs/tprofile/${samplerFileName}
#不注入的类加载器
excludeClassLoader = org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader
# 需要监控的包(分号分割)
includePackageStartsWith = com.test.data
# 不需要监控的包(分号分割)
excludePackageStartsWith = com.taobao;org.apache;com.alibaba
添加启动参数
-javaagent:bin/tprofiler-1.0.1.jar -Dprofile.properties=app-data/src/main/resources/TProfiler.properties
部署
添加启动参数后重新启动应用,根据TProfiler.properties中配置的日志路径找到三个日志文件,tprofiler.log,tmethod.log,tsampler.log
tprofiler.log
线程ID、方法栈深度、方法编号、耗时(毫秒)
tmethod.log
通过下面命令生成tmethod.log文件
>java -cp bin/tprofiler-1.0.1.jar com.taobao.profile.client.TProfilerClient 0.0.0.0 50000 flushmethod
flushmethod success
方法编号、方法在源码中最后一行的行号
topmethod.log
通过下面命令生成topmethod.log
>java -cp ~/app/bin/tprofiler-1.0.1.jar com.taobao.profile.analysis.ProfilerLogAnalysis tprofiler.log tmethod.log topmethod.log topobject.log
print result success
配合awk命令过滤出某个方法耗时
awk '$3==25 {print $1,$2,$3,$4}' tprofiler.log //查看编号为25的方法耗时情况
远程操控
//远程查看状态
java -cp tprofiler.jar com.taobao.profile.client.TProfilerClient 10.232.*.* 端口号 status
//远程开始
java -cp tprofiler.jar com.taobao.profile.client.TProfilerClient 10.232.*.* 端口号 start
//远程停止
java -cp tprofiler.jar com.taobao.profile.client.TProfilerClient 10.232.*.* 端口号 stop
//远程刷出方法数据
java -cp tprofiler.jar com.taobao.profile.client.TProfilerClient 10.232.*.* 端口号 flushmethod
优点
监控的方法全
日志体积小,适合线上长期使用
支持远程控制开关
使用方便,只有一个jar包
无本地代码
缺点
需要配置启动参数
功能单一,只能统计耗时,只提供文本展示