一、概述
Arthas
(阿尔萨斯)是阿里巴巴开源的一款Java诊断工具,用于实时检测、诊断Java应用程序的性能问题。它是一个命令行工具,提供了丰富的功能,包括查看类加载信息、方法执行耗时、线程堆栈、内存分析等 。Arthas
的设计目标是在生产环境中实时诊断和解决Java应用程序的问题。
以下是 Arthas
的一些主要特点和功能:
- 实时性:
Arthas
可以在运行中的Java
进程中实时进行诊断,无需重新启动应用。 - 丰富的命令:提供了众多的命令,涵盖了类加载、方法执行、线程、内存、
GC
等多个方面。 - 动态追踪:支持实时动态追踪方法调用、线程堆栈等信息,方便定位问题。
- 内存分析:提供了
Heap Dump
、Histogram
、Classloader Stats
等命令,帮助进行内存分析。 - 多种环境支持:支持
Linux
、Mac
和Windows
操作系统,支持HotSpot
和OpenJ9 JVM
。 - 在线帮助:提供了丰富的在线帮助,用户可以通过 help 命令查看每个命令的详细说明。
请注意,Arthas
的使用可能需要一些对 Java 应用程序的基本了解。在生产环境中使用 Arthas
时,需要谨慎操作,以免对应用程序产生影响。详细的使用方法和命令说明可以参考 Arthas
的官方文档:
- arthas.aliyun.com/doc/
- github.com/alibaba/art…。
二、Arthas 安装
全量安装
wget https://arthas.aliyun.com/download/latest_version?mirror=aliyun -O arthas-packaging-3.7.1-bin.zip
unzip arthas-packaging-3.7.1-bin.zip
[root@local-168-182-110 arthas]#l
total 32060
-rw-r--r-- 1 root root -rw-r--r-- 1 root root -rw-r--r-- 1 root root 142141 Sep 27 2020 arthas-boot.jar 430937 Sep 27 2020 arthas-client.jar 8087 Sep 27 2020 arthas-agent.jar
drwxr-xr-x 2 root root -rw-r--r-- 1 root root 13460738 Sep 27 2020 arthas-core.jar 6 Dec 3 15:14 arthas-output
-rw-r--r-- 1 root root 18702021 Aug 24 21:17 arthas-packaging-3.7.1-bin.zip
-rw-r--r-- 1 root root 531 Sep 27 2020 arthas.properties
-rw-r--r-- 1 root root -rwxr-xr-x 1 root root 5074 Sep 27 3117 Sep 27 2020 arthas-spy.jar 2020 as.bat
-rwxr-xr-x 1 root root 7744 Sep 27 2020 as-service.bat
-rwxr-xr-x 1 root root 33931 Sep 27 2020 as.sh
drwxr-xr-x 2 root root -rwxr-xr-x 1 root root drwxr-xr-x 2 root root -rw-r--r-- 1 root root 2020 Sep 27 635 Sep 27 2020 install-local.sh 199 Sep 27 2020 async-profiler 146 Sep 27 2020 lib 2020 logback.xmU
-rw-r--r-- 1 root root [root@local-168-182-110 arthas]# [root@local-168-182-110 arthas]# 4121 Sep 27 2020 math-game.jar
三、Arthas 主要组成结构
主要有以下几大组件:
arthas-core.jar
是服务器端的启动入口类,调用VirtualMachine#attach
到目标进程,并加载arthas-agent.jar
作为agent
包。arthas-agent.jar
既可以使用premain
方式(在目标进程启动之前,通过-agent
参数静态指定),也可以通过agentmain
方式(在进程启动之后attach
上去)。arthas-agent
会使用自定义的classloader(ArthasClassLoader)
加载arthas-core.jar
里面的Configure
类以及ArthasBootstrap
。 同时程序运行的时候会使用arthas-spy.jar
。arthas-spy.jar
里面只包含Spy
类,目的是为了将Spy
类使用BootstrapClassLoader
来加载,从而使目标进程的java应用可以访问Spy
类。通过ASM
修改字节码,可以将Spy类的方法ON_BEFORE_METHOD
,ON_RETURN_METHOD
等编织到目标类里面。arthas-client.jar
是客户端程序,用来连接arthas-core.jar
启动的服务端代码,使用telnet
方式。一般由arthas-boot.jar
和as.sh
来负责启动。
四、Arthas 通信主要流程
Arthas
应用是基于C/S
的通信架构来设计的,支持 Telnet
和 Http
的客户端协议通信。
在服务器端的启动过程中会调用 ArthasBootstrap#bind
中, 会启动 Telnet
和 Http
通信协议的服务器实例并接收请求。
服务器端接收到客户端连接后都会为每个连接生成会话窗口,并会将发过来的请求内容解析后生成命令交由任务控制去完成响应。
其中每个客户端通信都对应唯一的 ShellImpl
实现,里面包括了唯一的 Session
实例,并持有 JobControllerImpl
和 InternalCommandManager
对象用于组装出异步任务去执行这个命令。
InternalCommandManager
类记录了所有命令,通过名字可搜索到对应的命令实现类,这里Command类会被包装 AnnotatedCommand
类放入列表中。
五、Arthas 快速入门讲解
1)启动 Arthas
# 第一重方式
./as.sh
# 第二种方式(推荐)
java -jar arthas-boot.jar
[root@local-168-182-110 arthas]# [root@local-168-182-110 arthas]#java -jar_arthas-boot.jar [INF0] JAVA HOME:/opt/jdk1.8.0 212/jre进性骊 [INF0] arthas-boot vers ton:3.7.1 [INF0] Found existing java process, please choose one and input the serial number of the process, eg :1. Then hit ENTER. [1]:99095 org.apache.zookeeper.server.quorum.QuorumPeerMain 1 输入进程编号 [INF0] arthas home:/opt/arthas [INFO] The target process already listen port 3658, skip attach.
[INFo] arthas-client conect 127.0.0.13658
ARTHAS wiki https://arthas.aliyun.com/doc tutorials https://arthas. aliyun.com/doc/arthas-tutorials.html 3.7.1 vers ion main_class pid 99095 time
2023-12-03 15:14:29
[arthas@99095]$
2)基础命令介绍
# 启动服务
java -jar arthas-boot.jar
# 查看帮助
help
base64
:base64 编码转换,和 linux 里的 base64 命令类似cat
:打印文件内容,和 linux 里的 cat 命令类似cls
:清空当前屏幕区域echo
:打印参数,和 linux 里的 echo 命令类似grep
:匹配查找,和 linux 里的 grep 命令类似help
:查看命令帮助信息history
:打印命令历史keymap
:Arthas 快捷键列表及自定义快捷键pwd
:返回当前的工作目录,和 linux 命令类似quit
:退出当前 Arthas 客户端,其他 Arthas 客户端不受影响reset
:重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类session
:查看当前会话的信息stop
:关闭 Arthas 服务端,所有 Arthas 客户端全部退出tee
: 复制标准输入到标准输出和指定的文件,和 linux 里的 tee 命令类似version
:输出当前目标 Java 进程所加载的 Arthas 版本号
3)jvm 相关
# 启动服务
java -jar arthas-boot.jar
# 查看帮助
help
dashboard
:当前系统的实时数据面板getstatic
:查看类的静态属性heapdump
:dump java heap, 类似 jmap 命令的 heap dump 功能jvm
:查看当前 JVM 的信息logger
:查看和修改 loggermbean
:查看 Mbean 的信息memory
:查看 JVM 的内存信息ognl
:执行 ognl 表达式perfcounter
:查看当前 JVM 的 Perf Counter 信息sysenv
:查看 JVM 的环境变量sysprop
:查看和修改 JVM 的系统属性thread
:查看当前 JVM 的线程堆栈信息vmoption
:查看和修改 JVM 里诊断相关的 optionvmtool
:从 jvm 里查询对象,执行 forceGc
1、dashboard(实时数据面板)
dashboard
ID -1 -1 -1 -1 48 19 45 46 -1 47 -1 13 31 14
NAME GROUP PRIORITY STATE %CPU DELTA_TIME TIME INTERRUPTE DAEMON
C2 CompilerThread0 15.2 0.760 0:3.273 false true
C2 CompilerThread2 -1 6.26 0.313 0:2.939 false true
C2 CompilerThread1 -1 4.17 0.208 0:3.356 false true
C1 CompilerThread3 -1 2.4 0.120 0:1.449 false true
Timer-for-arthas-dashboard-7b1 system 5 RUNNABLE 0.63 0.031 0:0.097 false true
scheduling-1 main 5 TIMED_WAI 0.62 0.031 0:0.097 false false
arthas-NettyHttpTelnetBootstra system 5 RUNNABLE0.35 0.017 0:0.097 false true
arthas-NettyHttpTelnetBootstra system 5 RUNNABLE 0.12 0.006 0:0.053 false true
VM Periodic Task Thread Thread -1 0.06 0.003 0:0.025 false true
arthas-command-execute system 5 TIMED_WAI 0.05 0.002 0:0.178 false true
VM Thread -1 0.03 0.001 0:0.105 false true
Catalina-utility-1 main 1 TIMED_WAI 0.01 0.000 0:0.005 false false
http-nio-8080-ClientPoller main 5 RUNNABLE0.0 0.000 0:0.002 false true
Catalina-utility-2 main 1 WAITING 0.0 0.000 0:0.004 false false
Memory used total max usage GC
heap 208M 393M 3641M 5.72% gc.ps_scavenge.count 7
ps_eden_space 197M 253M 1351M 14.60% gc.ps_scavenge. time(ms) 33
ps_survivor_space code_cache ps_old_gen nonheap Memory 68M OK 13M 11M 13M 134M 6656K 71M 2731M -1 240M 6656K 96.15% 0.41% 0.00% 5.75% gc.ps_marksweep. time(ms) gc.ps_marksweep.count GC 79 2
metaspace 48M 50M -1 95.56%
Runtime os.name os.version java.version java.home systemload.average processors
Mac OS X 10.15.4
Runtime
1.8.0_151 /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/H ome/jre 2.48 8
数据说明:
ID
:Java级别的线程ID,注意这个ID不能跟jstack
中的nativeID
一一对应NAME
:线程名GROUP
:线程组名PRIORITY
:线程优先级,1~10
之间的数字,越大表示优先级越高STATE
:线程的状态CPU%
:线程消耗的cpu
占比,采样100ms
,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。TIME
:线程运行总时间,数据格式为分:秒INTERRUPTED
:线程当前的中断位状态DAEMON
:是否是daemon
线程
GC区域说明:
gc.ps_scavenge.count
:从应用程序启动到当前采样时间年轻代gc次数gc.ps_scavenge.time(ms)
:从应用程序启动到当前采样时间年轻代gc所用的总时间(毫秒)gc.ps_marksweep.count
:从应用程序启动到当前采样时间老年代gc次数gc.ps_marksweep.time(ms)
:从应用程序启动到当前采样时间老年代gc所用的总时间(毫秒)
Memory
区域主要参数说明:
heap
:堆内存使用情况(ps_eden_space+ps_survivor_space+ps_old_gen)ps_eden_space
:伊甸园区内存使用情况ps_survivor_space
:幸存区内存使用情况ps_old_gen
:老年代内存使用情况nonheap
:非堆内存使用情况
输入 q
或者 Ctrl+C
可以退出dashboard命令
2、Thread(线程相关堆栈信息)
参数说明:
- 数字:线程id
- [n:]:指定最忙的前N个线程并打印堆栈
- [b]:找出当前阻塞其他线程的线程
- [i ] :指定cpu占比统计的采样间隔,单位为毫秒
Arthas支持管道,可以用 thread 1 | grep 'main('<代码结束> 查找到
main class` 。
thread 1 | grep 'main('
thread # 显示所有线程的信息
thread 1 # 显示1号线程的运行堆栈
thread -b # 查看阻塞的线程信息
thread -n 3 # 查看最忙的3个线程,并打印堆栈
thread -i 1000 -n 3 # 指定采样时间间隔,每过1000毫秒采样,显示最占时间的3个线程
# 查看处于等待状态的线程(WAITING、BLOCKED)
thread --state WAITING
[arthas@99095]$ thread 74 "arthas-NettyHttpTelnetBootstrap-3-6" Id=74 RUNNABLE (in native) at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) at sun.nio.ch.EPollSelectorImpl. doSelect(EPollSelectorImpl. java:93) at sun.nio.ch.Selector Impl. lockAndDoSelect(SelectorImpl.java:86) at sun.nio.ch.Selector Impl.select(SelectorImpl.java:97) at sun.nio.ch.SelectorImpl.select(SelectorImpl. java:101) at com.al ibaba. arthas. deps. io.netty.channel.nto. SelectedSelect ionkeySetSelector.select(SelectedSelect ionkeySetSelector.java:68) at com.al ibaba.arthas.deps. io.netty.channel.nio
注意:本文归作者所有,未经作者允许,不得转载