Java诊断工具Arthas:开篇之watch实战
Arthas是阿里开源的线上监控诊断产品,用于问题的排查和诊断。
它的出现大大提高线上排查问题的效率,这篇只讲它一个非常牛逼的功能,其它功能往后篇章会在展开详细说。
一、Arthas能为你做什么?
1、遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
2、我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?直接反编译指定的类
3、某个接口执行过慢,如何定位是哪个服务?哪个方法?
4、有什么办法可以监控到 JVM 的实时运行状态?
5、这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
6、怎么快速定位应用的热点,生成火焰图?
二、问题表象
下面有一段模拟代码,该接口的作用是:
检查某一个商品是否为合格商品,但最终判定合格商品的条件是:颜色、包装都必须合格。
/**
* 检查该商品是否是合格产品
*
* @param goodsId 商品ID
* @return ture:合格
*/
@Override
public Boolean getPassCheck(Integer goodsId) {
boolean colourCheck = this.colourCheck(goodsId);
boolean packageCheck = this.packageCheck(goodsId);
//两种检查都通过才会返回True
boolean passCheck = colourCheck && packageCheck;
return passCheck;
}
//颜色检查
private Boolean colourCheck(Integer goodsId) {
//这里模拟做了颜色检查
return Boolean.TRUE;
}
//包装检查
private Boolean packageCheck(Integer goodsId) {
//这里模拟做了包装检查
return Boolean.FALSE;
}
这个接口上线后,测试人员向你反馈一个问题?
商品ID为1234的商品,明明是合格商品,但最终返回的是false(不合格),这是什么原因?
这个时候你看着代码,说不上是什么原因,有可能是颜色检查不通过,或者是包装检查不通过,也可能是都不通过。
但因为你没有打日志,所以你也无法判定到底是哪个导致的。
那怎么办?
按照以前做法,简单,加上日志就可以了
//颜色检查
private Boolean colourCheck(Integer goodsId) {
Boolean aTrue = Boolean.TRUE;
log.info("颜色检查 商品ID={},最终返回={}", goodsId, aTrue);
return aTrue;
}
//包装检查
private Boolean packageCheck(Integer goodsId) {
Boolean aTrue = Boolean.FALSE;
log.info("包装检查 商品ID={},最终返回={}", goodsId, aTrue);
return aTrue;
}
我们在重新发起请求
http://localhost:8080/test/getPassCheck?goodsId=9999
在看下日志
颜色检查 商品ID=9999,最终返回=true
包装检查 商品ID=9999,最终返回=false
恭喜你,问题找到了,是 包装检查 不合格。
但是这种方式,必须经历以下阶段:测试
、预发
,然后生产
。
这种方法效率低下,更糟糕的是,有些问题可能无法解决,因为一旦 JVM 重新启动,它可能无法复现。
那有没有好的解决办法。
当然有 Arthas就可以完美解决。
我们下面可以来演示下,如何在不添加日志的情况下,知道每一个方法的入参、出参是什么?
三、启动arthas
在命令行下面执行:
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
选择应用 java 进程:
* [1]: 8160 com.zhuangpo.event.MainApplication
[2]: 579
[3]: 8421 arthas-boot.jar
[4]: 8455 com.jincou.validation.ValidationApplication
选择你要查看的Java应用进程,上面的进程是第1个,则输入 1,再输入回车/enter。
Arthas 会 attach 到目标进程上,并输出日志:
[INFO] arthas home: /Users/xub/.arthas/lib/3.7.1/arthas
[INFO] Try to attach process 8160
Picked up JAVA_TOOL_OPTIONS:
[INFO] Attach process 8160 success.
[INFO] arthas-client connect 127.0.0.1 3658
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki https://arthas.aliyun.com/doc
tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html
version 3.7.1
main_class com.zhuangpo.event.MainApplication
pid 8160
time 2023-10-18 11:35:21
[arthas@8160]$
四、watch命令大显身手
watch命令:便于观察指定方法的调用情况。具体地,可以观察到:方法入参、方法返回值、方法抛出异常。
我们同样以上面的示例来演示下watch命令的使用。
因为我们只要要看到方法colourCheck
和 packageCheck
的返回值,就可以找到问题所在。
我们先看 colourCheck
(颜色检查) 方法
命令如下
watch com.zhuangpo.event.service.impl.ArthasTestServiceImpl colourCheck '{params,returnObj}' -n 5 -x 3
查看日志
查看packageCheck
包装检查方法
watch com.zhuangpo.event.service.impl.ArthasTestServiceImpl packageCheck '{params,returnObj}' -n 5 -x 3
从上面两张图执行结果,我们可以得出 颜色检查最终返回Ture,包装检查最终返回是False。所以问题就已经找到了。非常方便。
这里也会发现一个问题,就是arthas命令很长,很难记住有没有什么好办法?
当然有
下面介绍一个idea 插件,自动生成arthas相关命令
五、arthas idea插件
arthas idea plugin 更简单的使用 arthas 的 IDEA 插件,方便的构建各种 arthas 命令,复制到剪切板 然后到服务器上启动 arthas 执行命令
进入idea搜索 arthas idea
插件就可以。
下载成功后,当你想看哪一个方法的时候,只要在这个方法上右击:
这个时候只要把这个命令粘贴到指定位置就可以了。
相关文档
Arthas官方文档地址: https://arthas.aliyun.com/doc/
arthas idea插件GitHub地址:https://github.com/WangJi92/arthas-idea-plugin
声明: 公众号如需转载该篇文章,发表文章的头部一定要 告知是转至公众号: 后端元宇宙。同时也可以问本人要markdown原稿和原图片。其它情况一律禁止转载!