Arthas使用总结
题记
Arthas
是一款开源的java
诊断工具,通过集成现有JVM
工具和JVM
扩展API
实现更加方便的监控JVM
状态,线上问题排查,动态跟踪代码,class
热加载,采用命令交互的模式使我们可以方便的进行线上问题处理;
Arthas使用
上传客户端jar
包并启动
外网环境
直接执行:wget https://arthas.aliyun.com/arthas-boot.jar
下载完成后执行 java -jar arthas-boot.jar 启动 arthas
内网环境
下载全量包https://github.com/alibaba/arthas/tags
上传至服务器,并解压
执行install_local.sh
执行java -jar arthas-boot.jar 启动 arthas;
attach服务
attach
目标服务前,需要保证目标服务已启动且与arthas
服务为同一用户,且预先记录目标服务进程id
;
根据目标服务进程id
选择序号,再按Enter
完成绑定;
指令操作
常用功能
以下为arthas常用功能,涉及指令详情见下文,指令集-指令详情;
JVM性能监控
使用arthas的dashboard可以查看实时数据面板,包括线程,内存,垃圾回收等
例如:dashboard-i 200 -n 3
生产问题定位
arthas作为一款Java诊断工具最大的作用就是为了方便我们对服务问题进行定位,以下为几种比较有代表性的问题场景arthas的使用;
- 排查缺少详细日志的函数方法问题
传统方法需要改动代码加上日志然后重新上线观察;
现在使用arthas的
watch命令结合
ognl表达式,就可以对问题方法进行观测
例如:watch
【类全路径名】 【方法名】 ‘{params,returnObj,throwExp}’ -n 5 -x 3
需要注意的是使用
watch
命令观测高并发函数时最好使用-n限定观测次数;
-
排查某
java
类修改了未生效问题
传统方法需要将class
文件下载下来,在本地进行反编译再观察,使用arthas
的jad
命令可以在服务器上直接将class
文件进行反编译后输出,方便直观对比核实; -
排查本地难以复现,需要在特定环境进行复现的问题
传统方式只能根据现有日志和代码进行推测,使用arthas的TimeTunnel命令(tt)可以对目标函数方法进行持续观测和记录,还可以检索记录的调用记录进行再次的触发执行;
例如:控目标方法调用情况:tt -t 【类全路径名】 【方法名】 -
发现问题调用后查询详情:tt -i 【调用记录index】
-
还可以重新发起一次调用:tt -i 【调用记录index】 -p
排查接口耗时变长问题
使用arthas的trace命令,可以打印出接口请求链路中各函数执行时间,方便定位优化
例如:trace com.example.demo.arthas.user.UserController findUserById -n 5 --skipJDKMethod false
需要注意的是trace每次只能跟组一级方法的调用链路,虽然可以使用-E正则表达式或动态trace来一定程度上达到多层trace的效果,但是考虑到trace本身也会占用耗时且系统开销较贵,多层trace会导致最终要trace的类和函数很多,所以最好手动一层层排查;另外考虑到trace开销较大,所以使用时均要加上-n以限制监听次数;
排查CUP飙升问题或死锁问题
使用arthas的dashboard和thread命令,可以直接查看线程堆栈信息方便我们定位问题,其中cpu使用率与linux命令top -H -p 的线程%CPU类似,一段采样间隔时间内,当前JVM各个线程的增量cpu时间与采样间隔时间的比例 ;
例如:thread
查看当前最忙的2个线程并打印堆栈:thread -n 2
找出死锁线程:thread -d
目前只支持找出synchronized关键字阻塞住的线程,其他api锁如juc的lock还不支持;
注意事项
arthas
的增强命令都是通过字节码增强技术实现,会在指定类的方法中插入一些切面来实现数据统计和观测,因此在线上使用时,需要尽量明确需要观测的类、方法及条件,并限制监控时长和次数,并且诊断结束后要执行stop
命令或reset
命令将增强类还原;
简单问题修复
arthas
提供热更新代码功能redefine/retransform
,可以在不重启服务的情况换重新定义已加载的类;
修改错误文件
有两种方式
- 第一种是直接在服务器上将对应class文件反编译后使用vim修改java文件然后再编译为class文件;
- 第二种是在开发环境修改源码后编译成class文件再上传至服务端;
更新已加载类
两种方式
- 使用`redefine`命令:`redefine `【修改后的`class`文件】
- 使用
retransform
命令:retransform
【修改后的class
文件】
注意事项
以上方法只能修改已有方法,不允许新增
field/method
正在跑的函数,没有退出不能生效,只有再次入栈时更新才会生效;
redefine
命令与arthas
其他增强命令trace/watch/tt
等命令冲突,两者会相互重置所以推荐使用retransform
命令;
总结
arthas
利用JDK
提供的现有工具jstat
、jmap
、jstack
并对其信息进行汇总以实现dashboard命令这种动态统计极大的方便了对服务的排查与观测。还利用Instrumentation API
或者ASM
增强class
实现了无入侵式的数据采集功能,使我们可以针对单一方法的执行进行监控甚至实现热替换;
局限性
虽然
arthas
不需要对应用程序进行改造,但是还是需要将jar
包传入到服务端,使用指令交互来对服务进行诊断排查,然而在生产环境下,一般开发人员并不具备这种权限。另外arthas
对宿主机JVM
有一定程度上的入侵其增强功能如trace,monitor
等使用了切面技术来进行观测和数据统计,有一定的风险(详见arthas
,github
的Issues
版块),也会对执行效率产生一些影响;
指令集
arthas
采用了命令交互的模式,使用其功能需要了解以下命令ps
、可以使用<指令> -h
来查看指令帮助;
指令概述
基础命令
help——查看命令帮助信息
cat——打印文件内容,和linux里的cat命令类似
echo–打印参数,和linux里的echo命令类似
grep——匹配查找,和linux里的grep命令类似
tee——复制标准输入到标准输出和指定的文件,和linux里的tee命令类似
pwd——返回当前的工作目录,和linux命令类似
cls——清空当前屏幕区域
session——查看当前会话的信息
reset——重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所 有增强过的类
version——输出当前目标 Java 进程所加载的 Arthas 版本号
history——打印命令历史
quit——退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
stop——关闭 Arthas 服务端,所有 Arthas 客户端全部退出
keymap——Arthas快捷键列表及自定义快捷键
系统命令
dashboard——当前系统的实时数据面板
thread——查看当前 JVM 的线程堆栈信息
jvm——查看当前 JVM 的信息
sysprop——查看和修改JVM的系统属性
sysenv——查看JVM的环境变量
vmoption——查看和修改JVM里诊断相关的option
perfcounter——查看当前 JVM 的Perf Counter信息
logger——查看和修改logger
getstatic——查看类的静态属性
ognl——执行ognl表达式
mbean——查看 Mbean 的信息
heapdump——dump java heap, 类似jmap命令的heap dump功能
类命令
sc——查看JVM已加载的类信息
sm——查看已加载类的方法信息
jad——反编译指定已加载类的源码
mc——内存编绎器,内存编绎.java文件为.class文件
redefine——加载外部的.class文件,redefine到JVM里
retransform——加载外部的.class文件,retransform到JVM里
dump——dump 已加载类的 byte code 到特定目录
classloader——查看classloader的继承树,urls,类加载信息,使用classloader去getResource
增强命令
monitor——方法执行监控
watch——方法执行数据观测
trace——方法内部调用路径,并输出方法路径上的每个节点上耗时
stack——输出当前方法被调用的调用路径
tt——方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
指令详情
dashboard
实时统计系统面板参数
thread
查看当前线程信息,查看线程的堆栈
jad
反编译指定类的源码
mc
Memory Compiler/内存编译器,编译.java
文件生成.class
redefine
加载外部的.class文件,redefine jvm 已加载的类
retransform
加载外部的.class文件,retransform jvm 已加载的类
monitor
用来监控方法的执行情况
trace
监控方法内部调用路径,并输出方法路径上每个节点的耗时
watch
监控方法执行信息,可观察到出参,入参,异常信息,耗时
exit/quit
使用exit或quit命令可以退出arthas,但是只是退出客户端,arthasServer还会在目标进程中执行,可以通过再次启动arthas-boot.jar来再次链接进程;
sotp
彻底退出arthas
相关资料
官方文档:https://arthas.aliyun.com/doc/