# Java应用诊断说明 Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。 [官方文档](https://arthas.aliyun.com/doc/quick-start.html) ## 准备工作 查看服务器上是否已有`arthas-boot.jar`文件,如果不存在,通过以下命令将文件下载到当前目录 ```shell curl -O https://arthas.aliyun.com/arthas-boot.jar ``` > 如果应用运行在docker容器内,需要进入到docker中进行操作。 ### 进入docker 1. 运行`docker ps`,查看容器 ``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0b3a8b5d66d0 nginx:latest "/docker-entrypoint.…" 3 weeks ago Up 17 minutes nginx 0389efb8e1bd java:8 "nohup java -jar jdg…" 3 weeks ago Up 17 minutes jdgk-taizhou 0dd0a4380685 redis "docker-entrypoint.s…" 4 weeks ago Up 4 weeks 0.0.0.0:6379->6379/tcp ``` 2. 运行`docker exec -it 容器ID bash` 进入docker 3. 运行`ls` 查看当前目录是否存在`arthas-boot.jar`文件,有的话,直接进入以下环节 ## 使用 Arthas 诊断工具 1. 运行 `java -jar arthas-boot.jar` ``` [INFO] arthas-boot version: 3.5.5 [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. * [1]: 1 jdgk.jar ``` 2. 选择要诊断的java进行,输入 `1`(进程号) 回车,进入成功后如下显示 ``` [INFO] arthas home: /root/.arthas/lib/3.5.6/arthas [INFO] Try to attach process 1 [INFO] Attach process 1 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.5.6 main_class pid 1 time 2022-03-04 15:35:28 ``` 3. 运行相关命令查看进行信息 4. 退出arthas 如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。 如果想完全退出arthas,可以执行stop命令。 ### 生成火焰图 火焰图可以用来观察当前项目的应用热点。观察哪些方法耗时过长,便于后期项目优化。 ```shell # 开始采集 profiler start # 结束采集 profiler stop #火焰图 执行300秒自动结束 -e 参数用于docker容器内部运行 profiler start -d 300 -e itimer ``` 通过浏览器查看arthas-output下面的profiler结果 默认情况下,arthas使用3658端口,则可以打开: http://localhost:3658/arthas-output/ 查看到arthas-output目录下面的profiler结果 docker环境下因为端口没有映射到外部,无法通过浏览器查看,需要通过命令将文件复制到主机,再下载到本地进行查看 ```shell docker cp 容器ID:文件路径 主机文件路径 ``` ### 输入 `dashboard` 查看当前程序的线程和内存占用情况 ``` ID NAME GROUP PRIORI STATE %CPU DELTA_ TIME INTER DAEMON 10 http-nio-8080-exec- main 5 TIMED_ 11.02 0.550 0:13.3 false true 79 http-nio-8080-exec- main 5 TIMED_ 9.73 0.486 0:8.37 false true 80 http-nio-8080-exec- main 5 RUNNAB 8.3 0.414 0:7.19 false true 83 http-nio-8080-exec- main 5 TIMED_ 7.71 0.385 0:6.14 false true 10 http-nio-8080-exec- main 5 RUNNAB 6.34 0.316 0:4.09 false true 79 http-nio-8080-exec- main 5 RUNNAB 3.41 0.170 0:7.93 false true -1 GC task thread#1 (P - -1 - 1.05 0.052 1:58.8 false true -1 GC task thread#3 (P - -1 - 1.03 0.051 1:59.4 false true -1 GC task thread#0 (P - -1 - 1.03 0.051 1:59.2 false true -1 GC task thread#2 (P - -1 - 1.03 0.051 1:59.0 false true Memory used total max usage GC heap 2007M 3778M 984 ps_eden_space 517M 1056M gc.ps_scavenge.time 104570 66M 118M 118M (ms) ps_old_gen 1424M 2604M gc.ps_marksweep.cou 53 nonheap 325M 349M -1 nt code_cache 119M 120M 240M gc.ps_marksweep.tim 35355 metaspace 186M 206M -1 e(ms) Runtime os.name Linux os.version 3.10.0-514.26.2.el7.x86_64 java.version 1.8.0_111 ``` ### 输入 `thread` 查看当前所有线程 ``` Threads Total: 402, NEW: 0, RUNNABLE: 29, BLOCKED: 0, WAITING: 50, TIMED_WAITING : 313, TERMINATED: 0, Internal threads: 10 ID NAME GROUP PRIORI STATE %CPU DELTA_ TIME INTER DAEMON 22 http-nio-8080-exec- main 5 RUNNAB 13.26 0.026 0:8.87 false true 20 http-nio-8080-exec- main 5 RUNNAB 13.16 0.026 0:6.17 false true 12 http-nio-8080-exec- main 5 RUNNAB 12.55 0.025 0:7.64 false true 83 http-nio-8080-exec- main 5 RUNNAB 12.42 0.025 0:6.32 false true 83 http-nio-8080-exec- main 5 RUNNAB 12.32 0.024 0:5.01 false true 11 http-nio-8080-exec- main 5 RUNNAB 12.12 0.024 0:5.27 false true 11 http-nio-8080-exec- main 5 RUNNAB 12.05 0.024 0:3.32 false true 10 http-nio-8080-exec- main 5 RUNNAB 11.59 0.023 0:6.16 false true 11 arthas-command-exec system 5 RUNNAB 0.99 0.002 0:29.3 false true -1 VM Thread - -1 - 0.69 0.001 0:20.2 false true -1 C2 CompilerThread1 - -1 - 0.67 0.001 1:28.9 false true 83 http-nio-8080-exec- main 5 TIMED_ 0.12 0.000 0:3.71 false true 62 lettuce-nioEventLoo main 5 RUNNAB 0.06 0.000 0:2.13 false true 35 lettuce-nioEventLoo main 5 RUNNAB 0.04 0.000 0:14.9 false true -1 VM Periodic Task Th - -1 - 0.03 0.000 0:0.90 false true 80 http-nio-8080-Clien main 5 RUNNAB 0.01 0.000 0:3.26 false true 37 lettuce-eventExecut main 5 WAITIN 0.01 0.000 0:1.46 false true 18 Druid-ConnectionPoo main 5 WAITIN 0.01 0.000 0:0.97 false true 65 Spring session redi main 5 WAITIN 0.01 0.000 0:0.37 false false 47 org.springframework main 5 TIMED_ 0.01 0.000 0:0.64 false false 42 org.springframework main 5 TIMED_ 0.01 0.000 0:0.64 false false ``` ### 记录指定方法的每次调用环境现场 ```shell # 指定类 指定方法 tt -t cn.zjyjx.web.controller.buz.InfoController getRemind # 模糊类名 tt -t *LoginController newLoginIn ``` ### 反编译查看在线源码 ```shell # jad 类名 jad cn.zjyjx.web.controller.buz.InfoController # jad 类名 方法名 jad cn.zjyjx.web.controller.buz.InfoController getRemind ``` ### 函数执行数据观测 ```shell # watch 类名 方法名 watch demo.MathGame primeFactors -x 2 ``` 返回内容 > 观察表达式,默认值是{params, target, returnObj},对应下发内容 result ``` method=demo.MathGame.primeFactors location=AtExceptionExit ts=2021-08-31 15:22:57; [cost=0.220625ms] result=@ArrayList[ @Object[][ @Integer[-179173], ], @MathGame[ random=@Random[java.util.Random@31cefde0], illegalArgumentCount=@Integer[44], ], null, ] ```