线上性能问题排查利器-Btrace和TProfiler使用

线上性能问题排查利器

背景

遇到性能问题,一般的排查手段包括查监控,查日志,本机调试,远程调试,灰度等,如果是只在线上环境出现,可能需要进行日志埋点,重新上线。
缺点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=[, method=]? [, type=]? [, location=]?)
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%的降低(高峰期可以远程关闭此工具)

线上性能问题排查利器-Btrace和TProfiler使用_第1张图片
tprofiler.png

工具使用

打包
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

方法编号、方法在源码中最后一行的行号

线上性能问题排查利器-Btrace和TProfiler使用_第2张图片
![tprofiler.log.png](https://upload-images.jianshu.io/upload_images/15518684-fe143e67396fd4f6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

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
线上性能问题排查利器-Btrace和TProfiler使用_第3张图片
topmethod.png

配合awk命令过滤出某个方法耗时

awk '$3==25 {print $1,$2,$3,$4}' tprofiler.log  //查看编号为25的方法耗时情况
线上性能问题排查利器-Btrace和TProfiler使用_第4张图片
awk.png
远程操控
//远程查看状态
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包
无本地代码

缺点

需要配置启动参数
功能单一,只能统计耗时,只提供文本展示

你可能感兴趣的:(线上性能问题排查利器-Btrace和TProfiler使用)