在开发过程中经常遇到线上生产环境出现问题需要排查,但是排查的时候不能直接debug,只能通过输出日志定位问题位置,然后查看代码逻辑,万一没有输出关键业务日志,就更加难以找到具体原因了。特别是一些偶现的场景,只有特定参数才能触发bug,真是崩溃,又不能每次都打印入参出参,这时候用上arthas 无疑是雪中送炭。
在IDEA 中安装arthas 插件,可以方便快捷的帮我们快速生成对应的命令,提高效率。
IDEA setting -> Plugins -> arthas idea -> install -> ok
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YzOY9TbB-1669864880706)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fc8628fc9c454c7a912fe66015d6dc55~tplv-k3u1fbpfcp-watermark.image?)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YDHL9wwz-1669864880707)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f2c0f587525d4016b0272b997aa8b03a~tplv-k3u1fbpfcp-zoom-1.image)]
// 查看容器名称
docker ps
// 进⼊容器
docker exec -it ${docker_name} sh
// 下载并启动arthas
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
// 打印帮助信息
java -jar arthas-boot.jar -h
// 如果下载速度比较慢,可以使用 aliyun 的镜像
java -jar arthas-boot.jar --repo-mirror aliyun --use-http
dockerfile中配置:
// 安装arthas调试工具
COPY --from=arthas路径 /opt/arthas /opt/arthas
// 进⼊容器
docker exec -it ${docker_name} sh
// 下载并启动arthas
cd /opt/arthas
java -jar arthas-boot.jar
$ $ java -jar arthas-boot.jar
* [1]: 35542
输入 1,再输入回车/enter(也可以直接回车)。Arthas 会 attach 到目标进程上,并输出日志:
[INFO] Try to attach process 71560
[INFO] Attach process 71560 success.
[INFO] arthas-client connect 127.0.0.1 3658
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki: https://arthas.aliyun.com/doc
version: 3.0.5.20181127201536
pid: 71560
time: 2018-11-28 19:16:24
前面说到排查问题时,入参出参是很关键的,通过arthas watch 命令可以快速查看方法入参出参,不侵入代码,方便快捷。
在IDEA 中,找到需要监听的方法,使用arthas 插件生成监听命令,粘贴到arthas 运行窗口执行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S1Dfvsm7-1669864880707)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/80a395f06ffb4035af12cca3e80370b6~tplv-k3u1fbpfcp-zoom-1.image)]
[arthas@10]$ watch com.xxx.controller.XxxController list '{params,returnObj,throwExp}' -n 5 -x 3
Press Q or Ctrl+C to abort.
Affect(class count: 2 , method count: 2) cost in 317 ms, listenerId: 1
调用接口后输出
[arthas@10]$ watch com.xxx.controller.XxxController list '{params,returnObj,throwExp}' -n 5 -x 3
Press Q or Ctrl+C to abort.
Affect(class count: 2 , method count: 2) cost in 317 ms, listenerId: 1
method=com.xxx.controller.XxxController.list location=AtExit
ts=2022-10-10 19:08:28; [cost=744.848392ms] result=@ArrayList[
@Object[][
...
],
@ResponseBody[
...
]]
如果只是退出当前的连接,可以用quit或者exit命令。Attach 到目标进程上的 arthas 还会继续运行,端口会保持开放,下次连接时可以直接连接上。
如果想完全退出 arthas,可以执行stop命令。
定位问题后修复bug,想要验证的时候需要发布到开发环境验证,如果是使用Jenkins或k8s,至少需要个3-5分钟,如果没有一次修改成功,发布的时间就会成倍增长。如果只是调整简单的逻辑,可以使用arthas 热部署服务,简单快捷将修改后的代码编译上传到服务器,刷新应用,连应用都不需要重启,快的话只要几十秒,这个效率提升杠杠的。
只针对方法内部逻辑修改调整,新增属性(依赖注入)或新增⽅法不⽀持 热更新。
修改代码后编译代码ctrl+F9,使用arthas 插件生成热更新命令,粘贴到容器内部执行下(如果在arthas 进程中需要stop 退出后在执行热更新命令)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4zEHb0w1-1669864880707)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2e045157bbf04e378d1a6fd9cf86f2da~tplv-k3u1fbpfcp-zoom-1.image)]
docker exec -it ${docker_name} sh
curl -Lk "https://xxxx" | base64 --decode >arthas-idea-plugin-hot-swap.sh;chmod a+x arthas-idea-plugin-hot-swap.sh;./arthas-idea-plugin-hot-swap.sh;
如果遇到接口响应时间过长,就需要去排查代码在哪一步消耗了过多的时间。之前都是通过日志输出去跟踪,有了arthas 后,可以使用arthas trace 命令快速查看耗时,定位异常方法,提高优化效率。
在IDEA 中,找到需要监听的方法,使用arthas 插件生成命令,粘贴到arthas 运行窗口执行
[arthas@10]$ trace com.xxx list -n 5 --skipJDKMethod false
Press Q or Ctrl+C to abort.
Affect(class count: 2 , method count: 2) cost in 389 ms, listenerId: 2
`---ts=2022-10-11 13:54:46;thread_name=http-nio-9006-exec-9;id=4e;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@74500e4f
`---[426.125398ms] com.xxx:list()
`---[425.88533ms] org.springframework.cglib.proxy.MethodInterceptor:intercept() #57
`---[425.360587ms] com.xxx:list()
+---[0.070398ms] com.xxx:getDetail() #538
+---[0.031788ms]
...