docker 安装arthas进行线上问题排查

655 阅读4分钟

docker安装arthas

1.先将工具包放到linux中,此处已将tool文件夹包含arthas ,tools.jar文件

5909226bc34f6ec010713d4358921184.png tools.jar文件为jdk中jre/lib的文件,缺失该文件,arthas无法启动

2.查看目标容器,检查目标容器中java存放的地址,比如此次我们要排查gateway服务

输入 docker ps|grep gateway(注意此处应用docker ps,不是docker service ls)

dbe663a9cbed8a13d593cb352dd9d02a.png 获取到容器id号 e148bb441352

3.进入容器

命令 (docker exec -it e148bb441352 /bin/bash 或者 docker exec -it e148bb441352 /bin/sh)有些docker镜像不支持bin/bash,只支持bin/sh,不行要换另一种尝试

5ed6fbc2a2e21518c2906b4d7e284a35.png

4.查找java路径

which java

b57c6fbe78df869ed76dc069cf1fac3a.png

查看java版本

c0d0b2b7079d7ce723410729a8631f9b.png

此处可见容器内java是jre环境,不是jdk不包含jps,jmap,jstack等线上排查工具

jre环境我们需要补环境,因为arthas是依赖部分的jdk工具的,如(tool.jar ,jps等)

找到了java的路径后退出容器( ctrl+p ctrl+q)

5.拷贝文件到容器

  1. docker cp tool/tools.jar e148bb441352:/opt/jdk/jre/lib
  2. docker cp tool/tools.jar e148bb441352:/usr/bin/java
  3. docker cp tool/tools.jar e148bb441352:/usr/lib/jvm/java-1.8-openjdk/jre/lib

一版来说这三条选择一条,像上面这种情况java在/opt/jdk/bin/java,我们应该输入第一条,注意e148bb441352 处应为你的容器号

docker cp tool/arthas e148bb441352:/home

这条命令必须执行,补jre环境

6.重新进入容器,开始使用arthas排查问题

c99c3cac54eae231e1203248f8e81f38.png

启动arthas-boot.jar

java -jar arthas-boot.jar

2b2c16e74c68c79c83de5f2481c8666d.png 此处会报错,报环境中缺失了jps,因为docker中java进程一般来说pid为1,所以我们可以直接不使用jps查看进程的pid号

直接使用 java -jar arthas-boot.jar 1进入

pid=1 ; touch /proc/pid/cwd/.attachpid{pid}/cwd/.attach_pid{pid} && kill -SIGQUIT {pid} && sleep 2 && ls /proc/{pid}/root/tmp/.java_pid${pid}

如果失败,执行下面这条命令后重新执行上述命令,进入arthas

2e323974971f99c0a288b5bc106b4acd.png

成功进入arthas了

arthas排查问题

[arthas文档](arthas.aliyun.com/doc/command…)

建议安装一个idea配合使用这个工具

fc171693430ae5cdc3ee041df13d62fc.png

1.某个接口非常慢(Trace命令)

如果你能定位到某个接口非常慢,而不是整体都慢。我们可以直接监控这个接口

比如此处登录接口非常慢

f405df7cdbf84689a1e3b1ab23587e99.png 先定位这个接口在代码什么地方

9e1d7f30adf8e20b70fbe60cfe479659.png

6daa0e45c2413ab6993928cf4c81a035.png

按照上述操作步骤,较为重要排查代码运行时间应该是trace命令

选择后应为trace com.cdc.apiGateway.controller.UserLoginController userLoginByNewPassStra -n 5 --skipJDKMethod false

4cdd448b09724f1e9f72d2e3de5b0e56.png

具体参数调控参考 [arthas文档](arthas.aliyun.com/doc/command…)

请求进来之后

ff16677df5fab9bd693f8c66103ea9b2.png

假如此处调用了另外的rpc接口,而这个rpc接口实现逻辑非常复杂,你应该要跟到该servcei中查询里面的方法耗时。(注意service服务不是api)

2.检测方法入参,出参(watch命令)

83cfcfdb690be910f2d18ba70383686e.png

watch com.cdc.apiGateway.controller.UserLoginController userLoginByNewPassStra '{params,returnObj,throwExp}' -n 5 -x 3

3.排查cpu占用,内存占用情况(dashboard命令)

e9a5bc2187dcd9c74c628a95bd0d3aa6.png

每隔几秒打印一次检测状态,可以看出内存变化

4.排查某个接口调用频率(monitor)

  1. 监控方法统计(monitor)**

使用 monitor 统计 loopMethod 的调用频率和耗时:

5f7ba025a3186f062b2289bb1a54ae31.png

排查cpu高占用

  1. 查看整体状态(dashboard)

输出示例:

观察到线程 http-nio-8080-exec-5 占用了 **85% ** 的 CPU,记下线程 ID 23


**3. 查看线程堆栈(thread) **

输出示例:

进一步查看该线程的详细堆栈:

输出示例:

发现线程正在执行 MyService.loopMethod 方法,且代码行号为 20,可能是一个死循环。


**4. 跟踪方法耗时(trace) **

使用 trace 命令跟踪 loopMethod 的调用链路和耗时:

输出示例:

发现 loopMethod 方法被频繁调用,且单次执行时间极短,但累积导致 CPU 满载,可能内部有快速循环。

排查内存过高的情况

heapdump /tmp/xxx.hprof

拉下来该文件后使用jvisualvm进行分析

把.hprof文件拉到jvisualvm中

5f3688e9899e431250fb56e520b02d83.png

这里能看到堆中一些基础情况

a863fe6034f65dda4708657bc9410653.png

切换至Objects,看实际占用

7a80b2bcdbc658b7479596e7de70a312.png

点开看实际占用

fc03bf0c1148e0a7789cb5eb2399711e.png

采样时应该每隔10秒生成一次hprof文件,采集1分钟,分析在1分钟内,那种对象增加最快。从而定位问题