学会 Arthas!让你 3 年经验掌握 5 年功力
点击下方名片,设为星标!
回复“1024”获取2TB学习资源!
大家好,我是民工哥,今天给大家介绍一款调优神器 -- 阿里巴巴Arthas,可以帮助你的应用释放潜力。

介绍
阿里巴巴 Arthas 是一个诊断工具,可以用于监视、分析和解决 Java 应用程序的问题。使用 Arthas 的一个主要优点是,我们不需要修改代码,甚至不需要重新启动我们想要监视的 Java 服务。
在本教程中,我们将首先安装 Arthas,在此之后,通过一个简单的案例来演示 Arthas 的一些关键特性。
最后,由于 Arthas 是用 Java 编写的,因此它是跨平台的,可以在 Linux、macOS 和 Windows 上运行。
使用场景
这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
是否有一个全局视角来查看系统的运行状况?
有什么办法可以监控到 JVM 的实时运行状态?
怎么快速定位应用的热点,生成火焰图?
怎样直接从 JVM 内查找某个类的实例?
Arthas 支持 JDK 6+,支持 Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。
下载和入门
首先,我们可以通过直接下载链接或使用curl来下载 Arthas 库:
curl -O https://alibaba.github.io/arthas/arthas-boot.jar 现在,让我们通过运行带有-h(帮助)选项的 Arthas 来测试它是否工作:
java -jar arthas-boot.jar -h 如果成功,我们应该看到显示所有命令的帮助指南:
更多安装细节:https://arthas.aliyun.com/doc/install-detail.html
具体使用
启动 Arthas
现在,让我们运行 Arthas 可执行文件:
java -jar arthas-boot.jar Arthas 提示选择要附加到的进程:
[INFO] arthas-boot version: 3.1.7
[INFO] Found existing java process, please choose one and hit RETURN.
* [1]: 25500 com.baeldung.arthas.FibonacciGenerator
... 让我们选择名称为 com.baeldung.arthas.FibonacciGenerator 的进程。在此示例中,只需在列表中输入数字‘1’并按 Enter 即可。
Arthas 现在会附加到该进程并启动:
[INFO] Try to attach process 25500
[INFO] Attach process 25500 success.
... 一旦 Arthas 启动,我们就有一个提示符,可以发出不同的命令。我们可以使用 help 命令获取有关可用选项的更多信息。为了方便使用 Arthas,我们还可以使用 tab 键来自动完成其命令。
仪表盘
一旦 Arthas 启动,我们可以使用仪表盘。在这种情况下,我们通过输入 "dashboard" 命令来使用仪表盘。现在,我们可以看到一个详细的屏幕,其中包含多个面板和关于我们的 Java 进程的许多信息:
参数说明
ID #Java 级别的线程 ID,注意这个 ID 不能跟 jstack 中的 nativeID 一一对应。
NAME #线程名
GROUP #线程组名
PRIORITY #线程优先级, 1~10 之间的数字,越大表示优先级越高
STATE #线程的状态
CPU% #线程的 cpu 使用率。比如采样间隔 1000ms,某个线程的增量 cpu 时间为 100ms,则 cpu 使用率=100/1000=10%
DELTA_TIME #上次采样之后线程运行增量 CPU 时间,数据格式为秒
TIME#线程运行总 CPU 时间,数据格式为分:秒
INTERRUPTED #线程当前的中断位状态
DAEMON #是否是 daemon 线程 分析器
profiler 命令支持生成应用热点的火焰图。本质上是通过不断的采样,然后把收集到的采样结果生成火焰图。
profiler 命令基本运行结构是 profiler action [actionArg]
参数说明
启动分析器
$ profiler start
Started [cpu] profiling
#默认情况下,生成的是 cpu 的火焰图,即 event 为cpu。可以用--event参数来指定。 通过浏览器查看 arthas-output 下面的 profiler 结果
默认情况下,arthas 使用 3658 端口,则可以打开:http://localhost:3658/arthas-output/查看到arthas-output目录下面的 profiler 结果:
点击可以查看具体的结果:
容器相关
启动arthas-boot来进行诊断
$ docker exec -it math-game /bin/sh -c "java -jar /opt/arthas/arthas-boot.jar"
* [1]: 9 jar[INFO] arthas home: /opt/arthas
[INFO] Try to attach process 9
[INFO] Attach process 9 success.
[INFO] arthas-client connect 127.0.0.1 3658
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'wiki: https://arthas.aliyun.com/doc
version: 3.0.5
pid: 9
time: 2018-12-18 11:30:36 诊断 Docker 里的 Java 进程
docker exec -it ${containerId} /bin/bash -c "wget https://arthas.aliyun.com/arthas-boot.jar && java -jar arthas-boot.jar" 诊断 k8s 里容器里的 Java 进程
kubectl exec -it ${pod} --container ${containerId} -- /bin/bash -c "wget https://arthas.aliyun.com/arthas-boot.jar && java -jar arthas-boot.jar" 把 Arthas 安装到基础镜像里 可以很简单把 Arthas 安装到你的 Docker 镜像里。
FROM openjdk:8-jdk-alpine# copy arthas
COPY --from=hengyunabc/arthas:latest /opt/arthas /opt/arthas 如果想指定版本,可以查看具体的 tags:https://hub.docker.com/r/hengyunabc/arthas/tags
分析堆栈跟踪
thread 用来查看当前线程信息,查看线程的堆栈。
当没有参数时,显示第一页线程的信息,默认按照 CPU 增量时间降序排列,只显示第一页数据。
$ thread
Threads Total: 33, NEW: 0, RUNNABLE: 9, BLOCKED: 0, WAITING: 3, TIMED_WAITING: 4, TERMINATED: 0, Internal threads: 17
ID NAME GROUP PRIORITY STATE %CPU DELTA_TIME TIME INTERRUPT DAEMON
-1 C2 CompilerThread0 - -1 - 5.06 0.010 0:0.973 false true
-1 C1 CompilerThread0 - -1 - 0.95 0.001 0:0.603 false true
23 arthas-command-execute system 5 RUNNABLE 0.17 0.000 0:0.226 false true
-1 VM Periodic Task Thread - -1 - 0.05 0.000 0:0.094 false true
-1 Sweeper thread - -1 - 0.04 0.000 0:0.011 false true
-1 G1 Young RemSet Sampling - -1 - 0.02 0.000 0:0.025 false true
12 Attach Listener system 9 RUNNABLE 0.0 0.000 0:0.022 false true
11 Common-Cleaner InnocuousThrea 8 TIMED_WAI 0.0 0.000 0:0.000 false true
3 Finalizer system 8 WAITING 0.0 0.000 0:0.000 false true
2 Reference Handler system 10 RUNNABLE 0.0 0.000 0:0.000 false true
4 Signal Dispatcher system 9 RUNNABLE 0.0 0.000 0:0.000 false true
15 arthas-NettyHttpTelnetBootstra system 5 RUNNABLE 0.0 0.000 0:0.029 false true
22 arthas-NettyHttpTelnetBootstra system 5 RUNNABLE 0.0 0.000 0:0.196 false true
24 arthas-NettyHttpTelnetBootstra system 5 RUNNABLE 0.0 0.000 0:0.038 false true
16 arthas-NettyWebsocketTtyBootst system 5 RUNNABLE 0.0 0.000 0:0.001 false true
17 arthas-NettyWebsocketTtyBootst system 5 RUNNABLE 0.0 0.000 0:0.001 false true thread --all显示所有匹配的线程,显示所有匹配线程信息,有时需要获取全部 JVM 的线程数据进行分析。
thread id显示指定线程的运行堆栈
$ thread 1
"main" Id=1 WAITING on java.util.concurrent.CountDownLatch$Sync@29fafb28at sun.misc.Unsafe.park(Native Method)- waiting on java.util.concurrent.CountDownLatch$Sync@29fafb28at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231) thread --state 查看指定状态的线程
[arthas@28114]$ thread --state WAITING
Threads Total: 16, NEW: 0, RUNNABLE: 9, BLOCKED: 0, WAITING: 3, TIMED_WAITING: 4, TERMINATED: 0
ID NAME GROUP PRIORITY STATE %CPU DELTA_TIME TIME INTERRUPTE DAEMON
3 Finalizer system 8 WAITING 0.0 0.000 0:0.000 false true
20 arthas-UserStat system 9 WAITING 0.0 0.000 0:0.001 false true
14 arthas-timer system 9 WAITING 0.0 0.000 jvm
查看当前 JVM 信息
$ jvm
RUNTIME
--------------------------------------------------------------------------------------------------------------MACHINE-NAME 37@ff267334bb65JVM-START-TIME 2020-07-23 07:50:36MANAGEMENT-SPEC-VERSION 1.2SPEC-NAME Java Virtual Machine SpecificationSPEC-VENDOR Oracle CorporationSPEC-VERSION 1.8VM-NAME Java HotSpot(TM) 64-Bit Server VMVM-VENDOR Oracle CorporationVM-VERSION 25.201-b09INPUT-ARGUMENTS []CLASS-PATH demo-arthas-spring-boot.jarBOOT-CLASS-PATH /usr/lib/jvm/java-8-oracle/jre/lib/resources.jar:/usr/lib/jvm/java-8-oracle/jre/lib/rt.jar:/usr/lib/jvm/java-8-oracle/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jsse.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jce.jar:/usr/lib/jvm/java-8-oracle/jre/lib/charsets.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jfr.jar:/usr/lib/jvm/java-8-oracle/jre/classesLIBRARY-PATH /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib--------------------------------------------------------------------------------------------------------------CLASS-LOADING
--------------------------------------------------------------------------------------------------------------LOADED-CLASS-COUNT 7529TOTAL-LOADED-CLASS-COUNT 7529UNLOADED-CLASS-COUNT 0IS-VERBOSE false--------------------------------------------------------------------------------------------------------------COMPILATION
--------------------------------------------------------------------------------------------------------------NAME HotSpot 64-Bit Tiered CompilersTOTAL-COMPILE-TIME 14921(ms)--------------------------------------------------------------------------------------------------------------GARBAGE-COLLECTORS
--------------------------------------------------------------------------------------------------------------PS Scavenge name : PS Scavenge[count/time (ms)] collectionCount : 7collectionTime : 68PS MarkSweep name : PS MarkSweep[count/time (ms)] collectionCount : 1collectionTime : 47--------------------------------------------------------------------------------------------------------------MEMORY-MANAGERS
--------------------------------------------------------------------------------------------------------------CodeCacheManager Code CacheMetaspace Manager MetaspaceCompressed Class SpaceCopy Eden SpaceSurvivor SpaceMarkSweepCompact Eden SpaceSurvivor SpaceTenured Gen--------------------------------------------------------------------------------------------------------------MEMORY
--------------------------------------------------------------------------------------------------------------HEAP-MEMORY-USAGE init : 268435456(256.0 MiB)[memory in bytes] used : 18039504(17.2 MiB)committed : 181403648(173.0 MiB)max : 3817865216(3.6 GiB)NO-HEAP-MEMORY-USAGE init : 2555904(2.4 MiB)[memory in bytes] used : 33926216(32.4 MiB)committed : 35176448(33.5 MiB)max : -1(-1 B)--------------------------------------------------------------------------------------------------------------OPERATING-SYSTEM
--------------------------------------------------------------------------------------------------------------OS LinuxARCH amd64PROCESSORS-COUNT 3LOAD-AVERAGE 29.53VERSION 4.15.0-52-generic--------------------------------------------------------------------------------------------------------------THREAD
--------------------------------------------------------------------------------------------------------------COUNT 30DAEMON-COUNT 24PEAK-COUNT 31STARTED-COUNT 36DEADLOCK-COUNT 0--------------------------------------------------------------------------------------------------------------FILE-DESCRIPTOR
--------------------------------------------------------------------------------------------------------------MAX-FILE-DESCRIPTOR-COUNT 1048576OPEN-FILE-DESCRIPTOR-COUNT 100
Affect(row-cnt:0) cost in 88 ms. memory
查看 JVM 内存信息。
$ memory
Memory used total max usage
heap 32M 256M 4096M 0.79%
g1_eden_space 11M 68M -1 16.18%
g1_old_gen 17M 184M 4096M 0.43%
g1_survivor_space 4M 4M -1 100.00%
nonheap 35M 39M -1 89.55%
codeheap_'non-nmethods' 1M 2M 5M 20.53%
metaspace 26M 27M -1 96.88%
codeheap_'profiled_nmethods' 4M 4M 117M 3.57%
compressed_class_space 2M 3M 1024M 0.29%
codeheap_'non-profiled_nmethods' 685K 2496K 120032K 0.57%
mapped 0K 0K - 0.00%
direct 48M 48M - 100.00% 监视方法调用
我们可以使用Arthas来监视方法,这在调试应用程序的性能问题时非常方便。为此,我们可以使用monitor命令。
monitor命令需要一个-c <秒数>标志和两个参数 - 限定类名和方法名。
$ monitor -c 5 demo.MathGame primeFactors
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 94 ms.timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2018-12-03 19:06:38 demo.MathGame primeFactors 5 1 4 1.15 80.00%timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2018-12-03 19:06:43 demo.MathGame primeFactors 5 3 2 42.29 40.00%timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2018-12-03 19:06:48 demo.MathGame primeFactors 5 3 2 67.92 40.00%timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2018-12-03 19:06:53 demo.MathGame primeFactors 5 2 3 0.25 60.00%timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2018-12-03 19:06:58 demo.MathGame primeFactors 1 1 0 0.45 0.00%timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------2018-12-03 19:07:03 demo.MathGame primeFactors 2 2 0 3182.72 0.00%
监控方法参数
可以监测一个方法的入参和返回值。有些问题线上会出现,本地重现不了,这时这个命令就有用了。
条件表达式的例子
$ watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 68 ms.
ts=2018-12-03 19:36:04; [cost=0.530255ms] result=@ArrayList[@Integer[-18178089],@MathGame[demo.MathGame@41cf53f9],
] 更多参考:https://arthas.aliyun.com/doc/watch.html
命令列表
基础命令
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 版本号 jvm 相关
dashboard #当前系统的实时数据面板
getstatic #查看类的静态属性
heapdump #dump java heap, 类似 jmap 命令的 heap dump 功能
jvm #查看当前 JVM 的信息
logger #查看和修改 logger
mbean #查看 Mbean 的信息
memory #查看 JVM 的内存信息
ognl #执行 ognl 表达式
perfcounter #查看当前 JVM 的 Perf Counter 信息
sysenv #查看 JVM 的环境变量
sysprop #查看和修改 JVM 的系统属性
thread #查看当前 JVM 的线程堆栈信息
vmoption #查看和修改 JVM 里诊断相关的 option
vmtool #从 jvm 里查询对象,执行 forceGc class/classloader 相关
classloader #查看 classloader 的继承树,urls,类加载信息,使用 classloader 去 getResource
dump #dump 已加载类的 byte code 到特定目录
jad #反编译指定已加载类的源码
mc #内存编译器,内存编译.java文件为.class文件
redefine #加载外部的.class文件,redefine 到 JVM 里
retransform #加载外部的.class文件,retransform 到 JVM 里
sc #查看 JVM 已加载的类信息
sm #查看已加载类的方法信息 monitor/watch/trace 相关
monitor #方法执行监控
stack #输出当前方法被调用的调用路径
trace #方法内部调用路径,并输出方法路径上的每个节点上耗时
tt #方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
watch #方法执行数据观测 总结
在本教程中,我们探索了Arthas的一些最强大和有用的功能。
正如我们所见,Arthas有许多命令可以帮助我们诊断各种问题。当我们无法访问正在审查的应用程序的代码,或者我们想快速诊断在服务器上运行的有问题的应用程序时,它也可以特别有帮助。
参考资料:
官方文档:https://arthas.aliyun.com/doc/
Arthas的GitHub仓库地址:https://github.com/alibaba/arthas
读者专属技术群
构建高质量的技术交流社群,欢迎从事后端开发、运维技术进群(备注岗位,已在技术交流群的请勿重复添加)。主要以技术交流、内推、行业探讨为主,请文明发言。广告人士勿入,切勿轻信私聊,防止被骗。
扫码加我好友,拉你进群

推荐阅读 点击标题可跳转
36 张图,一次性补全你的网络知识短板!
面试官:如何在 Docker 容器中抓包?问倒一大片
又一款轻量级监控利器!开源了
去了一家不到20人的IT公司后,真的是大开眼界
目前工资最高的外包公司汇总(2023最新版)!
卸载 Postman!事实证明,它更牛逼。。。
果真有这样的公司,够横!直接干上了热搜

PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。点“在看”支持我们吧!
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
