Arthas
概述
Arthas
是Alibaba开源的Java诊断工具,深受开发者喜爱。
当你遇到以下类似问题而束手无策时,Arthas
可以帮助你解决:
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到JVM的实时运行状态?
- 怎么快速定位应用的热点,生成火焰图?
- 怎样直接从JVM内查找某个类的实例?
1. 启动math-game
curl -O https://arthas.aliyun.com/math-game.jar
java -jar math-game.jar
math-game
是一个简单的程序,每隔一秒生成一个随机数,再执行质因数分解,并打印出分解结果。
2. 启动arthas
在命令行下面执行(使用和目标进程一致的用户启动,否则可能attach失败):
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
- 执行该程序的用户需要和目标进程具有相同的权限。比如以
admin
用户来执行:sudo su admin && java -jar arthas-boot.jar
或sudo -u admin -EH java -jar arthas-boot.jar
。 - 如果attach不上目标进程,可以查看
~/logs/arthas/
目录下的日志。 - 如果下载速度比较慢,可以使用aliyun的镜像:
java -jar arthas-boot.jar --repo-mirror aliyun --use-http
java -jar arthas-boot.jar -h
打印更多参数信息。
选择应用java进程:
$ $ java -jar arthas-boot.jar
* [1]: 35542
[2]: 71560 math-game.jar
math-game
进程是第2个,则输入2,再输入回车/enter
。Arthas会attach到目标进程上,并输出日志:
需要注意的是 arthas在连接了一个java程序之后,需要断开才能连接第二个,不让会报如下错
[ERROR] The telnet port 3658 is used by process 149108 instead of target process 120344, you will connect to an unexpected process.
[ERROR] 1. Try to restart arthas-boot, select process 149108, shutdown it first with running the 'stop' command.
[ERROR] 2. Or try to stop the existing arthas instance: java -jar arthas-client.jar 127.0.0.1 3658 -c "stop"
[ERROR] 3. Or try to use different telnet port, for example: java -jar arthas-boot.jar --telnet-port 9998 --http-port -1
常用指令
1、dashboard
使用dashboard指令可以看到当前进程的信息。
2、thread
使用thread指令可以看到所有线程信息,指定具体的pid可以看到线程的具体信息。
-n参数:可以查看最繁忙的三个线程
-b参数:查看死锁的线程,同时可以看到谁被谁锁住了
-i参数:指定采样间隔
3、jad
使用这条指令可以反编译class文件,参数为包名+类名
除了可以直接反编译class文件外,还可以仅仅反编译方法
4、watch
可以查看方法的入参、返回值、抛出异常、运行时间与运行时间点等信息,第一个参数为包名.类名,第二个参数为方法名,第三个参数为ognl表达式,指为返回值。
使用ognl表达式查看入参与出参
-b参数为方法执行前,获取入参
target获取所有属性
-s,后置参数
5、pwd
显示当前工作目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v8FwWn7j-1657012075664)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646535255865.png)]
6、session
查看当前会话的信息,第一个为java进程的id,第二个为arthas追踪的会话信息。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-on4xW5mA-1657012075664)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646536213988.png)]
7、reset
还原被arthas增强过的类,arthas服务端关闭时会自动重置所有的增强类。
8、trace
追踪指定方法的执行信息,包括线程信息,优先级,类加载器,执行时间
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tlS1hFDZ-1657012075665)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646536643436.png)]
还可以看到执行指定方法的耗时,红色时间代表最耗时的部分。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9hzS3mvR-1657012075666)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646577732304.png)]
输出耗时大于0.5毫秒的方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cJkk9v5q-1657012075666)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646577958079.png)]
9、keymap
查看所有的快捷键
10、jvm
显示jvm所有的基本信息,如操作系统、线程信息、文件信息。
11、sysprop
查看和修改jvm属性
查看:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qvUmVCpA-1657012075667)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646545709574.png)]
修改的话,查看命令后面跟上值就可以了。
12、sysenv
查看系统属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AR8yD16f-1657012075667)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646546129353.png)]
13、vmoption
查看和修改虚拟机相关参数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dF4OtVZR-1657012075668)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646546347554.png)]
14、getstatic
查看类的静态属性。
15、ognl
ognl表达式: OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
使用ognl调用方法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Re8m2N2b-1657012075668)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646547132769.png)]
使用ognl获取属性,效果同getstatic
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R4LUc07t-1657012075669)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646547222170.png)]
除此之外还可以生成对象
16、sc
搜索类的信息,-d参数可以获取详细信息,-df还可以获取属性的信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5HlhA2tP-1657012075670)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646550255819.png)]
17、sm
获取方法信息 -d获取详细信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wZvcNM8D-1657012075671)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646550415960.png)]
18、mc
编译java文件为class文件
19、redefine
将新增或修改后的文件动态的加载到jvm中,注意:正在运行的class文件不能redefine。
如下案例为动态修改在运行的class文件,并让他运行。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R5R1iQgp-1657012075672)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646551175122.png)]
20、dump
将已加载的字节码文件保存到特定目录。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TxkHdGWh-1657012075672)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646551856111.png)]
21、classloader
这个命令可以将所有的类加载器统计出来,并展示各自统计的类个数,也可以指定类加载器去获取resource,打印出resource的路径,对于ResourceNotFoundException比较有用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rul1xOEF-1657012075673)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646552403971.png)]
-l参数,展示父类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yeDLis8h-1657012075674)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646552489211.png)]
-c参数 可以找到类加载所在的包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xn2hdg8m-1657012075674)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646552744692.png)]
-r参数可以通过类加载器找到指定文件在哪个目录下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gTVUsQsm-1657012075675)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646552984718.png)]
-load 可以指定类加载器加载指定class文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HCbtbY1D-1657012075676)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646553197239.png)]
22、monitor
监控指定类方法的执行情况
一下为每隔5秒返回一次demo.MathGame类的primeFactors方法的执行情况
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D9EDAa0Z-1657012075677)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646553918223.png)]
23、stack
输出当前方法被调用的调用路径
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BYhGwn0z-1657012075677)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646578188238.png)]
过滤方法第一个入参小于0,执行两次的调用路径[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m5OFInQL-1657012075678)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\1646578342916.png)]
24、tt
watch
虽然很方便和灵活,但需要提前想清楚观察表达式的拼写,这对排查问题而言要求太高,因为很多时候我们并不清楚问题出自于何方,只能靠蛛丝马迹进行猜测。
tt -t参数可以看到方法的具体执行时间,耗时,是否成功,并且后期还可以看到执行的结果。
-t
tt 命令有很多个主参数,-t
就是其中之一。这个参数的表明希望记录下类 *Test
的 print
方法的每次执行情况
-
条件表达式
不知道大家是否有在使用过程中遇到以下困惑
- Arthas 似乎很难区分出重载的方法
- 我只需要观察特定参数,但是 tt 却全部都给我记录了下来
条件表达式也是用
OGNL
来编写,核心的判断对象依然是Advice
对象。除了tt
命令之外,watch
、trace
、stack
命令也都支持条件表达式。 -
解决方法重载
tt -t *Test print params.length==1
通过制定参数个数的形式解决不同的方法签名,如果参数个数一样,你还可以这样写
tt -t *Test print 'params[1] instanceof Integer'
-
解决指定参数
tt -t *Test print params[0].mobile=="13989838402"
25、option
全局开关
可以设置option
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TPDdEImw-1657012075678)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\image-20220313122053957.png)]
26、profiler
profiler
命令支持生成应用热点的火焰图。本质上是通过不断的采样,然后把收集到的采样结果生成火焰图。
启动profiler
$ profiler start
Started [cpu] profiling
默认情况下,生成的是cpu的火焰图,即event为
cpu
。可以用--event
参数来指定。
获取已采集的sample的数量
$ profiler getSamples
23
查看profiler状态
$ profiler status
[cpu] profiling is running for 4 seconds
可以查看当前profiler在采样哪种event
和采样时间。
停止profiler
生成html格式结果
默认情况下,结果文件是html
格式,也可以用--format
参数指定:
$ profiler stop --format html
profiler output file: /tmp/test/arthas-output/20211207-111550.html
OK
或者在--file
参数里用文件名指名格式。比如--file /tmp/result.html
。
点击可以查看具体的结果:
含义:
$ profiler status
[cpu] profiling is running for 4 seconds
可以查看当前profiler在采样哪种`event`和采样时间。
## 停止profiler
### 生成html格式结果
默认情况下,结果文件是`html`格式,也可以用`--format`参数指定:
$ profiler stop --format html
profiler output file: /tmp/test/arthas-output/20211207-111550.html
OK
或者在`--file`参数里用文件名指名格式。比如`--file /tmp/result.html` 。
点击可以查看具体的结果:
[外链图片转存中...(img-6LFbVsP1-1657012075679)]
含义:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-To4j9g0u-1657012075680)(C:\Users\Ric\Desktop\每日总结\后端\arthas\Arthas\image-20220313123008638.png)]