关于 Arthas
Arthas 是一款开源在线 Java 诊断工具,采用命令行交互模式,支持 web 端在线诊断,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。得益于 Arthas 强大且丰富的功能,让 Arthas 能做的事情超乎想象。
它可以帮你解决这些问题:
1、以全局视角来查看系统的运行状况、健康状况。
2、反编译源码,查看jvm加载的是否为预期的文件内容。
3、查看某个方法的返回值,参数等等。
4、方法内调用路径及各方法调用耗时。
5、查看jvm运行状况。
6、外部.class文件重新加载到jvm里。
等等…
场景:
1)调用接口时,接口返回异常信息,如果该异常信息没有清晰的定位到代码,那么我们通常只能依靠大脑回忆代码,来估计错误发生地了,如果无法估计,一般情况下就会进入测试环境,模拟复现,如果无法复现 _。
2)这个查询,耗时20s,我们想要分析一下到底是哪些代码导致的。但是该方法内部又穿插调用了其它业务功能方法,难道手写System.currentTimeMillis()自己做减运算,还是guava的StopWatch亦或是commons的StopWatch?这几种方式需要我们手动嵌入代码,容易遗漏、费力还费时。
安装&启动
可以去文档中自行下载 Arthas用户文档
下载后拿到artha-boot.jar 放至服务器内,cd到目录下,启动jar包
java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.4.6 [INFO] Found existing java process,
please choose one and input the serial number of the process, eg : 1.
Then hit ENTER.
- [1]: 23271 org.apache.catalina.startup.Bootstrap
序号1就是我们的服务器java项目的pid 如果出现多个就代表服务器有多个java项目。
输入我们要操作的服务器的序号就可以成功启动了。如下图
相关命令
仅以主要的几个命令作为展示,具体命令及参数可以参阅官方文档。
1.监控service包下的所有方法 每5秒刷新一次
monitor -c 5 com.jeefw.service.* *
2.监控A类下的 test 方法
trace *A test
3.监控AdsPlatformRevenueServiceImpl 类下的 getPlatformRevenueVO 方法 执行时的参数和返回值
watch *AdsPlatformRevenueServiceImpl getPlatformRevenueVO "{params,returnObj}" -x 3
4.反编译 AdminJobImpl类下的 updateExperienceMembersDispatch方法
jad *AdminJobImpl updateExperienceMembersDispatch
5.输入dashboard,回车,仪表盘显示当前进程相关信息。
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
| ①Thread相关信息
| 线程id 线程名称 线程组 线程优先级 线程状态 线程消耗的cpu百分比 运行总时间 线程当前的中断位状态 是否守护线程
| ID NAME GROUP PRIORITY STATE %CPU TIME INTERRUPTED DAEMON
| 188 Timer-for-arthas-dashboard-f5864b5b-762a-4fb5-8cc5-65559bd6 system 10 RUNNABLE 19 0:0 false true
| 36 pool-1-thread-1 main 5 TIMED_WAITING 5 0:1 false false
| 33 Abandoned connection cleanup thread main 5 TIMED_WAITING 0 0:0 false true
| 179 AsyncAppender-Worker-arthas-cache.result.AsyncAppender system 9 WAITING 0 0:0 false true
| 12 AsyncFileHandlerWriter-225534817 main 5 TIMED_WAITING 0 0:0 false true
| 94 Attach Listener system 9 RUNNABLE 0 0:0 false true
| 70 ContainerBackgroundProcessor[StandardEngine[Catalina]] main 5 TIMED_WAITING 0 0:0 false true
| 34 Druid-ConnectionPool-Create-300669762 main 5 WAITING 0 0:0 false true
| 35 Druid-ConnectionPool-Destroy-300669762 main 5 TIMED_WAITING 0 0:0 false true
| 3 Finalizer system 8 WAITING 0 0:0 false true
| 13 GC Daemon system 2 TIMED_WAITING 0 0:0 false true
| 14 NioBlockingSelector.BlockPoller-1 main 5 RUNNABLE 0 0:0 false true
| 15 NioBlockingSelector.BlockPoller-2 main 5 RUNNABLE 0 0:0 false true
| 2 Reference Handler system 10 WAITING 0 0:0 false true
| 4 Signal Dispatcher system 9 RUNNABLE 0 0:0 false true
| 76 ajp-nio-38009-Acceptor-0 main 5 RUNNABLE 0 0:0 false true
| 74 ajp-nio-38009-ClientPoller-0 main 5 RUNNABLE 0 0:0 false true
| 75 ajp-nio-38009-ClientPoller-1 main 5 RUNNABLE 0 0:0 false true
| 187 as-command-execute-daemon system 10 TIMED_WAITING 0 0:0 false true
| 73 http-nio-37080-Acceptor-0 main 5 RUNNABLE 0 0:0 false true
| 71 http-nio-37080-ClientPoller-0 main 5 RUNNABLE 0 0:0 false true
| 72 http-nio-37080-ClientPoller-1 main 5 RUNNABLE 0 0:0 false true
|
| ②内存信息 ③垃圾回收
| Memory used total max usage GC
| (堆) (垃圾回收次数)
| heap 424M 1897M 1897M 22.37% gc.ps_scavenge.count 19
| (伊甸园) (垃圾回收消耗时间)
| ps_eden_space 311M 387M 403M 77.28% gc.ps_scavenge.time(ms) 1405
| (幸存者区) (标记-清除算法的次数)
| ps_survivor_space 40M 144M 144M 27.74% gc.ps_marksweep.count 3
| (老年代) (标记-清除算法的消耗时间)
| ps_old_gen 72M 1365M 1365M 5.32% gc.ps_marksweep.time(ms) 446
| (非堆区)
| nonheap 137M 141M -1 97.49%
| (代码缓存区)
| code_cache 40M 41M 240M 16.99%
| (元空间)
| metaspace 86M 89M -1 97.09%
| (压缩空间)
| compressed_class_space 10M 10M 1024M 0.99%
| direct 80K 80K - 100.00%
| mapped 0K 0K - NaN%
|
| ④运行信息
| Runtime
| os.name Linux
| os.version 3.10.0-957.1.3.el7.x86_64
| java.version 1.8.0_101
| java.home /opt/jdk1.8.0_101/jre
| systemload.average 0.03
| processors 8
| uptime 11956s
|________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
说明
ID: Java级别的线程ID,注意这个ID不能跟jstack中的nativeID一一对应
NAME: 线程名
GROUP: 线程组名
PRIORITY: 线程优先级, 1~10之间的数字,越大表示优先级越高
STATE: 线程的状态
CPU%: 线程消耗的cpu占比,采样100ms,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。
TIME: 线程运行总时间,数据格式为分:秒
INTERRUPTED: 线程当前的中断位状态
DAEMON: 是否是daemon线程
通过上述信息,可以帮助我们快速定位相关问题线程。