一文带你快速了解 Java 线上问题快速诊断神器 Arthas

Posted zuozewei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一文带你快速了解 Java 线上问题快速诊断神器 Arthas相关的知识,希望对你有一定的参考价值。

一、什么是 Arthas

Arthas 是 Alibaba开源的一款 Java 诊断工具,能够查看 Java 应用的线程状态、JVM 信息等,支持在线对业务问题诊断,比如查看方法调用的出入参、执行过程、抛出的异常、输出方法执行耗时等,大大提升了线上问题的排查效率。

官网:https://arthas.aliyun.com/zh-cn/

二、特性一览

三、Arthas 能为你做什么?

你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:

  1. 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  2. 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
  3. 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
  4. 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
  5. 是否有一个全局视角来查看系统的运行状况?
  6. 有什么办法可以监控到JVM的实时运行状态?
  7. 怎么快速定位应用的热点,生成火焰图?
  8. 怎样直接从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的主要内容,如果未能解决你的问题,请参考以下文章

一文带你快速了解 Spark 架构设计与原理思想

性能测试如何定位瓶颈?偶发超时?看高手如何快速排查问题

一文带你快速初步了解云计算与大数据

一文带你了解怎样快速上手微信小程序开发

都2023年了,Servlet还有必要学习吗?一文带你快速了解Servlet

Java 线上问题排查神器 Arthas 快速上手与原理浅谈