Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。
Arthas 支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。
Github: https://github.com/alibaba/arthas
文档: https://arthas.aliyun.com/doc/index.html
Arthas Install
快速安装
使用arthas-boot
下载arthas-boot.jar,然后用java -jar的方式启动:
1 | curl -O https://arthas.aliyun.com/arthas-boot.jar |
打印帮助信息:
1 | java -jar arthas-boot.jar -h |
如果下载速度比较慢,可以使用aliyun的镜像:
1
java -jar arthas-boot.jar --repo-mirror aliyun --use-http
如果从github下载有问题,可以使用gitee镜像
1
wget https://arthas.gitee.io/arthas-boot.jar
使用as.sh
Arthas 支持在 Linux/Unix/Mac 等平台上一键安装,请复制以下内容,并粘贴到命令行中,敲 回车 执行即可:
1 | curl -L https://alibaba.github.io/arthas/install.sh | sh |
上述命令会下载启动脚本文件 as.sh 到当前目录,你可以放在任何地方或将其加入到 $PATH 中。
直接在shell下面执行./as.sh,就会进入交互界面。
也可以执行./as.sh -h来获取更多参数信息。
如果从github下载有问题,可以使用gitee镜像
1 | curl -L https://arthas.gitee.io/install.sh | sh |
全量安装
最新版本,点击下载:arthas
解压后,在文件夹里有arthas-boot.jar,直接用java -jar的方式启动:
1 | java -jar arthas-boot.jar |
卸载
- 在 Linux/Unix/Mac 平台
删除下面文件:
1 | rm -rf ~/.arthas/ |
- Windows平台直接删除user home下面的.arthas和logs/arthas目录
常用命令
所有命令参考文档: https://alibaba.github.io/arthas/commands.html
watch
https://arthas.aliyun.com/doc/watch.html
方法执行数据观测
让你能方便的观察到指定方法的调用情况。能观察到的范围为:返回值、抛出异常、入参,通过编写 OGNL 表达式进行对应变量的查看。
参数
class-pattern 类名表达式匹配
method-pattern 方法名表达式匹配
express 观察表达式
condition-express 条件表达式
[b] 在方法调用之前观察
[e] 在方法异常之后观察
[s] 在方法返回之后观察
[f] 在方法结束之后(正常返回和异常返回)观察
[E] 开启正则表达式匹配,默认为通配符匹配
[x:] 指定输出结果的属性遍历深度,默认为 1
watch实践
查看内部方法有没有被调用,以及是否抛出异常
1 | watch com.xxx.bbc.opsu.buyerlibrary.service.impl.BuyerTagMemberOriginalInfoServiceImpl updateTair "{throwExp,params,returnObj}" -x 2 -n 2 |
-x 2 查看参数的深度
-n 2 只执行两次,调用量大的情况来不及停止。
tt
方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测。
记录
1 | tt -t -n3 com.a.b queryIsxxx |
查看记录列表
1 | tt -l |
结果分别是
1 | INDEX - 索引 |
查看详情
1 | tt -i [INDEX] |
利用ognl表达式查看
1 | tt -i 1002 -w '{params[0],returnObj.success}' |
重放请求
1 | tt -i 1002 -p |
jad/mc/redefine
jad
反编译指定已加载类的源码
默认情况下,反编译结果里会带有ClassLoader信息,通过--source-only选项,可以只打印源代码。方便和mc/redefine命令结合使用。
参数:
- class-pattern
类名表达式匹配 - [c:]
类所属 ClassLoader 的 hashcode - [E]
开启正则表达式匹配,默认为通配符匹配
exp:
1 | jad --source-only com.xxx.china.buyer.odps.OdpsTaskServiceImpl > /tmp/OdpsTaskServiceImpl.java |
1 | jad org.apache.log4j.Logger -c 69dcaba4 |
mc
Memory Compiler/内存编译器,编译.java文件生成.class。
[c:]
指定classloader[d:]
指定输出目录
注意,mc命令有可能失败。如果编译失败可以在本地编译好.class文件,再上传到服务器。
exp
1 | mc -c 5b275dab -d /tmp/ /tmp/OdpsTaskServiceImpl.java |
redefine
加载外部的.class文件,redefine jvm已加载的类。注意, redefine后的原来的类不能恢复,redefine有可能失败(比如增加了新的field),参考jdk本身的文档:Instrumentation#redefineClasses
参数
- [c:]
ClassLoader的hashcode - [p:]
外部的.class文件的完整路径,支持多个
exp:
1 | redefine -c 5b275dab /tmp/com/xxx/china/buyer/odps/OdpsTaskServiceImpl.class |
上传 .class 文件到服务器的技巧:
使用mc命令来编译jad的反编译的代码有可能失败。可以在本地修改代码,编译好后再上传到服务器上。有的服务器不允许直接上传文件,可以使用base64命令来绕过。
在本地先转换.class文件为base64,再保存为result.txt
1
base64 < Test.class > result.txt
到服务器上,新建并编辑result.txt,复制本地的内容,粘贴再保存
把服务器上的 result.txt还原为.class
1
base64 -d < result.txt > Test.class
用md5命令计算哈希值,校验是否一致
redefine的限制
- 不允许新增加field/method
- 正在跑的函数,没有退出不能生效
表达式核心变量
无论是匹配表达式也好、观察表达式也罢,他们核心判断变量都是围绕着一个 Arthas 中的通用通知对象 Advice 进行。它的简略代码结构如下
1 | public class Advice { |
所有变量都可以在表达式中直接使用,如果在表达式中编写了不符合 OGNL 脚本语法或者引入了不在表格中的变量,则退出命令的执行;用户可以根据当前的异常信息修正条件表达式或观察表达式