Arthas(阿尔萨斯)是阿里开源的一个Java在线分析诊断工具.
wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar --target-ip 0.0.0.0
使用arthas调试项目,项目服务必须要运行,arthas启动后会自动检测本地所有java服务并列出来,我们只需要按照序号输入想要调试的项目.
curl -L https://alibaba.github.io/arthas/install.sh | sh
执行上面的命令会在所在的文件中生成as.sh执行文件
启动
./as.sh PID #进程id 指定JAVA进程id
使用Arthas服务的web console必须对外暴露本机地址(线上环境不推荐)
# --target-ip就是Arthas对外暴露的ip
java -jar arthas-boot.jar --target-ip 172.18.205.100
java -jar arthas-boot.jar --telnet-port 9999 --http-port -1
./as.sh --target-ip 0.0.0.0
./as.sh --telnet-port 9999 --http-port -1
访问 172.18.205.100:9999,进入Arthas web控制台.
quit 退出当前arthas客户端
exit 通quit
stop 关闭Arthas服务端,所有客户端退出
显示当前java进程的详细信息
# 展示所有的线程列表
thread
thread-all
# cpu使用率采样修改为2s,默认为200ms
thread -i 2000
# 打印出cpu使用率前5的线程详情,即比较繁忙的线程,cpu使用率采样统计方式请参考官方文档说明
thread -n 5
# 打印id为5的线程详情
thread 5
# 根据状态过滤线程数据(NEW, RUNNABLE, TIMED_WAITING, WAITING, BLOCKED, TERMINATED)
thread --state RUNNABLE
thread |grep RUNNABLE
# 列出持有某个锁,阻塞其他线程最多的线程,排查死锁
thread -b
查看类的加载器信息
# 查看类加载器,及加载信息
classloader
# 查看类加载器hash、parent信息
classloader -l
# 查看类加载器之间的继承树
classloader -t
# 列出所有类加载器及加载的类
classloader -a
# 查看URLClassLoader实际的urls
classloader -c hashcode
查看jvm中某个类的信息
# 模糊匹配类信息,支持正则表达式,如果是接口,还会列出所有的实现类
sc java.lang.String*
# 模糊匹配类信息,限制最多匹配到的数量,默认100
sc java.lang.String* -n 2
# 查看类详情信息
sc -d java.lang.String
# 指定类加载器查看类信息
sc -c hashcode java.lang.String*
# 查看类详情信息,包含field信息
sc -d -f java.lang.String
查看jvm中类的方法
# 查看某个类下所有的方法信息
sm com.zlm.arthasdemo.controller.UController
# 查看某个类下的某个方法信息
sm com.zlm.arthasdemo.controller.UController AllUser
# 查看方法详情
sm -d com.zlm.arthasdemo.controller.UController AllUser
# 指定类加载器查看类下某个方法的详细信息
sm -c hashcode -d com.zlm.arthasdemo.controller.UController AllUser
查看方法的执行详情
# 限制观测执行次数
watch *UserController helloUser -n 2
# 设置观测结果遍历深度
wathch *UserController helloUser -x 2
# 只观测执行成功
watch *UserController helloUser -s
# 只观测执行失败
watch *UserController helloUser -e
# 同时观测方法执行前、方法执行后结果
watch *UserController helloUser -b -f
# 观测方法执行异常时,详细的异常栈信息
watch *UserController helloUser '{throwExp}' -e -x 2
# 观测方法执行时间大于200ms的信息
watch *UserController helloUser '#cost>100'
查看方法内部调用路径,并输出方法路径1上的每个节点上耗时
# 观测方法内部调用顺序及耗时
trace com.zlm.arthasdemo.controller.UserController helloUser
# 观测方法内部调用顺序及耗时,只观测3次
trace com.zlm.arthasdemo.controller.UserController helloUser -n 3
# 观测方法内部调用顺序及耗时,包含jdk内部方法
trace com.zlm.arthasdemo.controller.UserController helloUser --skipJDKMethod false
# 限制观测范围,第一个参数长度大于10
trace com.zlm.arthasdemo.controller.UserController helloUser params[0].length>=10
# 限制观测范围,执行耗时大于100ms
trace com.zlm.arthasdemo.controller.UserController helloUser '#cost>100'
# trace 同时多个类的多个方法
trace -E com.test.ClassA|org.test.ClassB method1|method2|method3
# 查找到具体的类信息
sc -d *UserController
# 使用ognl表达式查看日志属性的信息,判断日志级别
ognl -c classLoaderHash "@com.zlm.arthasdemo.controller.UserController@logger"
# 使用ognl表达式修改日志级别
ognl -c classLoaderHash "@[email protected](@ch.qos.logback.classic.Level@DEBUG)"
# 再次查看日志级别,判断是否修改成功
ognl "@com.zlm.arthasdemo.controller.UserController@logger"
# 修改全局日志级别
ognl -c classLoaderHash '@org.slf4j.LoggerFactory@getLogger("root").setLevel(@ch.qos.logback.classic.Level@DEBUG)'