使用arthas 快速排查问题(查看出入参,方法执行时间和热更新)

前言

在开发过程中经常遇到线上生产环境出现问题需要排查,但是排查的时候不能直接debug,只能通过输出日志定位问题位置,然后查看代码逻辑,万一没有输出关键业务日志,就更加难以找到具体原因了。特别是一些偶现的场景,只有特定参数才能触发bug,真是崩溃,又不能每次都打印入参出参,这时候用上arthas 无疑是雪中送炭。

1、IDEA中的配置

在IDEA 中安装arthas 插件,可以方便快捷的帮我们快速生成对应的命令,提高效率。

1.1、安装插件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?)]

1.2、arthas配置阿里云oss 或Redis(用于热部署)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YDHL9wwz-1669864880707)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f2c0f587525d4016b0272b997aa8b03a~tplv-k3u1fbpfcp-zoom-1.image)]

2、安装启动arthas

2.1、快速启动

// 查看容器名称
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

2.2、将arthas 打包到镜像中,启动容器后直接运行

dockerfile中配置:

// 安装arthas调试工具
COPY --from=arthas路径 /opt/arthas /opt/arthas
// 进⼊容器 
docker exec -it ${docker_name} sh 
// 下载并启动arthas
cd /opt/arthas
java -jar arthas-boot.jar	

2.3、选择应用 java 进程

$ $ 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

3、监听方法出入参

前面说到排查问题时,入参出参是很关键的,通过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[
		...
	]]

4、退出arthas

如果只是退出当前的连接,可以用quit或者exit命令。Attach 到目标进程上的 arthas 还会继续运行,端口会保持开放,下次连接时可以直接连接上。

如果想完全退出 arthas,可以执行stop命令。

5、热更新服务

定位问题后修复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;

6、监控追踪方法执行时间

如果遇到接口响应时间过长,就需要去排查代码在哪一步消耗了过多的时间。之前都是通过日志输出去跟踪,有了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] 
                ...

你可能感兴趣的:(java,docker,intellij-idea)