一文带你快速了解 Java 线上问题快速诊断神器 Arthas
Posted zuozewei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一文带你快速了解 Java 线上问题快速诊断神器 Arthas相关的知识,希望对你有一定的参考价值。
一、什么是 Arthas
Arthas 是 Alibaba开源的一款 Java 诊断工具,能够查看 Java 应用的线程状态、JVM 信息等,支持在线对业务问题诊断,比如查看方法调用的出入参、执行过程、抛出的异常、输出方法执行耗时等,大大提升了线上问题的排查效率。
官网:https://arthas.aliyun.com/zh-cn/
二、特性一览
三、Arthas 能为你做什么?
你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到JVM的实时运行状态?
- 怎么快速定位应用的热点,生成火焰图?
- 怎样直接从JVM内查找某个类的实例?
Arthas 支持 JDK 6+,支持 Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。
四、快速安装
1、前提条件
[root@c41287379b7c /]# yum install telnet
[root@c41287379b7c /]# yum install unzip
2、一键安装
使用命令下载 Arthas 脚本:
[root@c41287379b7c /]# curl -L https://alibaba.github.io/arthas/install.sh | sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 961 100 961 0 0 743 0 0:00:01 0:00:01 --:--:-- 743
downloading... ./as.sh.1598
Arthas install successed.
使用命令下载 Arthas jar包:
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
Arthas 提供是 jar 包形式,其本质是个 Java 应用。
五、快速使用
1、启动脚本并连接进程
使用脚本快速启动:
[root@c41287379b7c /]# ./as.sh
Arthas script version: 3.1.7
[INFO] JAVA_HOME: /usr/jdk1.8.0_111
Found existing java process, please choose one and hit RETURN.
* [1]: 1 org.apache.catalina.startup.Bootstrap
1 //这里输入1就是连接进程,如果有多个java进程,将在这里出现一个list,输入序号即可连接进程。
updating version 3.1.7 ...
Download arthas from: https://repo1.maven.org/maven2/com/taobao/arthas/arthas-packaging/3.1.7/arthas-packaging-3.1.7-bin.zip
######################################################################## 100.0%
Archive: /tmp/temp_3.1.7_1673/arthas-3.1.7-bin.zip
creating: /tmp/temp_3.1.7_1673/async-profiler/
inflating: /tmp/temp_3.1.7_1673/arthas-spy.jar
inflating: /tmp/temp_3.1.7_1673/arthas-agent.jar
inflating: /tmp/temp_3.1.7_1673/arthas-client.jar
inflating: /tmp/temp_3.1.7_1673/arthas-boot.jar
inflating: /tmp/temp_3.1.7_1673/arthas-demo.jar
inflating: /tmp/temp_3.1.7_1673/install-local.sh
inflating: /tmp/temp_3.1.7_1673/as.sh
inflating: /tmp/temp_3.1.7_1673/as.bat
inflating: /tmp/temp_3.1.7_1673/as-service.bat
inflating: /tmp/temp_3.1.7_1673/async-profiler/libasyncProfiler-linux-x64.so
inflating: /tmp/temp_3.1.7_1673/async-profiler/libasyncProfiler-mac-x64.so
inflating: /tmp/temp_3.1.7_1673/arthas-core.jar
update completed.
Arthas home: /root/.arthas/lib/3.1.7/arthas
Calculating attach execution time...
Attaching to 1 using version /root/.arthas/lib/3.1.7/arthas...
real 0m2.298s
user 0m0.302s
sys 0m0.145s
Attach success.
telnet connecting to arthas server... current timestamp is 1583537651
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \\ | .--. ''--. .--'| '--' | / O \\ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\\ \\ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki https://alibaba.github.io/arthas
tutorials https://alibaba.github.io/arthas/arthas-tutorials
version 3.1.7
pid 1
time 2020-03-06 23:34:10
[arthas@1]$
2、启动 jar 包并连接进程
执行该程序的用户需要和目标进程具有相同的权限。
比如以 admin用户来执行:
sudo su admin && java -jar arthas-boot.jar
或
sudo -u admin -EH java -jar arthas-boot.jar
如果attach不上目标进程,可以查看 ~/logs/arthas/
目录下的日志。
如果下载速度比较慢,可以使用aliyun的镜像:
java -jar arthas-boot.jar --repo-mirror aliyun --use-http
java -jar arthas-boot.jar -h #打印更多参数信息。
选择应用java进程:
$ $ java -jar arthas-boot.jar
* [1]: 35542
[2]: 71560 math-game.jar
math-game 进程是第2个,则输入2,再输入回车 /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: 2020-11-28 19:16:24
$
出现 Arthas Logo 之后便可以正常使用了。
六、使用示例
1、dashboard(当前系统的实时数据面板)
ID NAME GROUP PRIORITY STATE %CPU TIME INTERRUPTE DAEMON
1572 http-nio-8080-exec-139 main 5 TIMED_WAITI 18 0:12 false true
1561 http-nio-8080-exec-138 main 5 RUNNABLE 17 0:18 false true
1539 http-nio-8080-exec-131 main 5 TIMED_WAITI 10 1:17 false true
1575 http-nio-8080-exec-141 main 5 TIMED_WAITI 10 0:0 false true
1573 http-nio-8080-exec-140 main 5 TIMED_WAITI 9 0:8 false true
1559 http-nio-8080-exec-136 main 5 TIMED_WAITI 8 0:29 false true
1558 grpc-default-executor-1340 main 5 TIMED_WAITI 4 0:5 false true
28 grpc-default-worker-ELG-1-4 main 5 RUNNABLE 4 6:44 false true
1560 http-nio-8080-exec-137 main 5 RUNNABLE 4 0:23 false true
Memory used total max usage GC
heap 155M 311M 843M 18.47% gc.ps_scavenge.count 6631
ps_eden_space 39M 171M 310M 12.72% gc.ps_scavenge.time(ms) 52792
ps_survivor_space 1M 2M 2M 90.63% gc.ps_marksweep.count 21
ps_old_gen 114M 138M 632M 18.10% gc.ps_marksweep.time(ms) 11572
Runtime
os.name Linux
os.version 3.10.0-1062.9.1.el7.x86_64
java.version 1.8.0_111
java.home /usr/jdk1.8.0_111/jre
2、sysprop(查看或修改java属性)
//查看所有属性
[arthas@1]$ sysprop
KEY VALUE
---------------------------------------------------------------------------------------------------------------------------------------
java.vendor Oracle Corporation
sun.java.launcher SUN_STANDARD
catalina.base /apache-tomcat-8.5.9
sun.management.compiler HotSpot 64-Bit Tiered Compilers
......
java.specification.versio 1.8
n
[arthas@1]$
//查看特定属性
[arthas@1]$ sysprop java.rmi.server.hostname
java.rmi.server.hostname=106.54.17.234
[arthas@1]$ sysprop file.encoding
file.encoding=ANSI_X3.4-1968
[arthas@1]$
//修改属性
[arthas@1]$ sysprop user.country
user.country=US
[arthas@1]$ sysprop user.country CN
Successfully changed the system property.
user.country=CN
3、mbean(实时查看Mbean信息)
参数-i 1000
是指定1秒刷新一次。
[arthas@1]$ mbean -i 1000 java.lang:type=Threading *Count
NAME VALUE
--------------------------------
PeakThreadCount 61
DaemonThreadCount 51
ThreadCount 59
TotalStartedThreadCount 1586
4、thread(查看线程)
//查看所有线程
[arthas@1]$ thread
Threads Total: 59, NEW: 0, RUNNABLE: 24, BLOCKED: 0, WAITING: 9, TIMED_WAITING: 26, TERMINATED: 0
ID NAME GROUP PRIORIT STATE %CPU TIME INTERRU DAEMON
1572 http-nio-8080-exec-139 main 5 TIMED_W 17 1:32 false true
1597 http-nio-8080-exec-151 main 5 RUNNABL 15 0:10 false true
1539 http-nio-8080-exec-131 main 5 TIMED_W 11 2:37 false true
1591 http-nio-8080-exec-148 main 5 RUNNABL 11 0:23 false true
1587 http-nio-8080-exec-146 main 5 TIMED_W 9 0:33 false true
1585 grpc-default-executor-1 main 5 TIMED_W 5 0:9 false true
......
Affect(row-cnt:0) cost in 106 ms.
[arthas@1]$
从上面查看所有的 threads 来看 1572 消耗CPU 17%(此百分比是按单 CPU 计算的)。所以需要查看这个线程在做什么。
//查看指定线程栈信息
[arthas@1]$ thread 1572
"http-nio-8080-exec-139" Id=1572 RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:170)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:100)
at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:143)
at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:173)
- locked com.mysql.jdbc.util.ReadAheadInputStream@afb14dd
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2954)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3375)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3365)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3805)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
- locked com.mysql.jdbc.JDBC4Connection@21123f41
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
- locked com.mysql.jdbc.JDBC4Connection@21123f41
at com.mysql.jdbc.PreparedStatement.execute$original$vADsw8UZ(PreparedStatement.java:1192)
- locked com.mysql.jdbc.JDBC4Connection@21123f41
at com.mysql.jdbc.PreparedStatement.execute$original$vADsw8UZ$accessor$md9IHdH2(PreparedStatement.java)
......
Number of locked synchronizers = 1
- java.util.concurrent.ThreadPoolExecutor$Worker@31355af3
Affect(row-cnt:0) cost in 152 ms.
[arthas@1]$
5、thread -n(查看占CPU前几的线程栈信息)
查看占 CPU 前 3 的线程栈,间隔 1 秒。
[arthas@1]$ thread -n 3 -i 1000
"http-nio-8080-exec-153" Id=1604 cpuUsage=31% RUNNABLE
at java.lang.Throwable.fillInStackTrace(Native Method)
at java.lang以上是关于一文带你快速了解 Java 线上问题快速诊断神器 Arthas的主要内容,如果未能解决你的问题,请参考以下文章