当涉及到 Java 应用程序的诊断和调优时,Arthas 是一款备受推崇的开源工具,无论是线上问题的定位,还是实时性能监控和分析,Arthas 都能为您提供强大的支持。
本文将介绍 Arthas 的常用命令和使用技巧,帮助您更好地利用该工具进行故障排查和性能优化。
一、前言
在开始本文之前,先推荐两个东西:
一个是 Arthas 官网:https://arthas.aliyun.com/doc/,官方文档对 Arthas 的每个命令都做出了介绍和解释,并且还有在线教程,方便大家学习和熟悉命令。
另外还有一个向大家推荐的是一款名为 Arthas Idea 的 IDEA 插件。
这是一款能快速生成 Arthas命令的插件,可快速生成可用于该类或该方法的 Arthas 命令,大大提高排查问题的效率。
二、常用命令
尽管 Arthas 命令众多,但在实际使用中我们只需聚焦于那些常用命令。本文旨在重点介绍这些常用命令,并提供使用技巧和最佳实践,帮助您更好地运用 Arthas。
1.类命令
(1) getstatic
查看类的静态属性。推荐直接使用 ognl 命令,更加灵活。
# getstatic class_name field_name
getstatic demo.MathGame random
# 如果该静态属性是一个复杂对象,还可以支持在该属性上通过 ognl 表达式进行遍历,过滤,访问对象的内部属性等操作。
# 例如,假设 n 是一个 Map,Map 的 Key 是一个 Enum,我们想过滤出 Map 中 Key 为某个 Enum 的值,可以写如下命令
getstatic com.alibaba.arthas.Test n 'entrySet().iterator.{? #this.key.name()=="STOP"}'
(2) jad
反编译指定已加载类的源码。jad 只能反编译单个类,如需批量下载指定包的目录的 class 字节码请使用 dump 命令。
比如我们想知道自己提交的代码是否生效了,这种场景jad 命令就特别有用。
# 反编译 java.lang.String
jad java.lang.String
# 默认情况下,反编译结果里会带有 ClassLoader 信息,通过 --source-only 选项,可以只打印源代码。方便和 mc/retransform 命令结合使用。
jad --source-only java.lang.String
# 反编译指定的函数
jad java.lang.String substring
# 当有多个 ClassLoader 都加载了这个类时,jad 命令会输出对应 ClassLoader 实例的 hashcode
# 然后你只需要重新执行 jad 命令,并使用参数 -c 就可以反编译指定 ClassLoader 加载的那个类了
jad org.apache.log4j.Logger -c 69dcaba4
(3) retransform
加载外部的 .class 文件,retransform jvm 已加载的类。
# 结合 jad/mc 命令使用,jad 命令反编译,然后可以用其它编译器,比如 vim 来修改源码
jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java
# mc 命令来内存编译修改过的代码
mc /tmp/UserController.java -d /tmp
# 用 retransform 命令加载新的字节码
retransform /tmp/com/example/demo/arthas/user/UserController.class
加载指定的 .class 文件,然后解析出 class name,再 retransform jvm 中已加载的对应的类。每加载一个 .class 文件,则会记录一个 retransform entry。
如果多次执行 retransform 加载同一个 class 文件,则会有多条 retransform entry。
# 查看 retransform entry
retransform -l
# 删除指定 retransform entry,需要指定 id:
retransform -d 1
# 删除所有 retransform entry
retransform --deleteAll
# 显式触发 retransform
retransform --classPattern demo.MathGame
如果对某个类执行 retransform 之后,想消除 retransform 的影响,则需要:
- 删除这个类对应的 retransform entry。
- 重新显式触发 retransform。
retransform 的限制:
- 不允许新增加 field/method。
- 正在跑的函数,没有退出不能生效。
使用 mc 命令来编译 jad 的反编译的代码有可能失败。可以在本地修改代码,编译好后再上传到服务器上。有的服务器不允许直接上传文件,可以使用 base64 命令来绕过。
- 在本地先转换 .class 文件为 base64,再保存为 result.txt。
base64 -i /tmp/test.class -o /tmp/result.txt
- 到服务器上,新建并编辑 result.txt,复制本地的内容,粘贴再保存。
vim /tmp/result.txt
- 把服务器上的 result.txt 还原为.class。
base64 -d /tmp/result.txt > /tmp/test.class
- 用 md5 命令计算哈希值,校验是否一致。
md5sum /tmp/test.class
2.监测排查命令
监测排查命令是 Arthas 中最常用的命令。
请注意,这些命令,都通过字节码增强技术来实现的,会在指定类的方法中插入一些切面来实现数据统计和观测,因此在线上、预发使用时,请尽量明确需要观测的类、方法以及条件,诊断结束要执行 stop 或将增强过的类执行 reset 命令。
(1) monitor
方法执行监控。可对方法的调用次数,成功次数,失败次数等维度进行统计。
# -b:计算条件表达式过滤统计结果(方法执行完毕之前),默认是方法执行之后过滤
# -c:统计周期,默认值为 120 秒
# params[0]