arthas上手
环境要求
jdk:jdk1.6+
注意这里是jdk而不是jre,因为jre中不包含jvm调试工具,比如jps、jmap、jstack等
下载
方式一:arthas-boot.jar的方式【推荐】
curl -O https://arthas.aliyun.com/arthas-demo.jar
方式二:as.sh的方式
curl -L https://arthas.aliyun.com/install.sh | sh
方式三:全量下载
在maven仓库或github上下载
安装和启动
启动自己的实验程序
启动下载好的arthas-boot.jar
在java进程列表中找到自己实验用的java进程序号,并键入
开始自动下载、安装,并启动程序
启动成功,开始使用

-
安装后的文件目录
image-20210122194556317.png
简单arthas诊断示例
示例一:sc
[arthas@12989]$ sc com.example.*
com.example.arthas.Arthas1Application
com.example.arthas.Arthas1Application
com.example.arthas.Arthas1Application$$EnhancerBySpringCGLIB$$fb9c1821
com.example.arthas.MathUtil
指令解释:查看 com.example.*包下的类加载情况
示例二:sm
[arthas@12989]$ sm com.example.arthas.MathUtil
com.example.arthas.MathUtil <init>()V
com.example.arthas.MathUtil calSum(II)V
Affect(row-cnt:2) cost in 34 ms.
指令解释:查看com.example.arthas.MathUtil类的方法加载情况
示例三:monitor
[arthas@12989]$ monitor -c 5 com.example.arthas.MathUtil calSum
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 88 ms, listenerId: 5
timestamp class method total succes fail avg-rt(ms) fail-rate
------------------------------------------------------------------------------------------------------------
2021-01-22 19:15:42 com.example.arthas.MathUtil calSum 2 2 0 2002.13 0.00%
指令解释:查看com.example.arthas.MathUtil类中calSum方法的运行情况,每5秒打印一次
示例四:dashboard
[arthas@12989]$ dashboard
指令解释:查看仪表盘,打印thread、memory、runtime(运行环境)信息

退出
方式一:退出当前session
键入exit或quit或q,关闭当前Session(客户端)
方式二:彻底退出
键入stop命令,停止arthas-server,其他attach到该java进程的Session也会被退出
arthas用于生产
arthas tunnel server搭建
字面意思,该组件是连接arthas server的隧道,将多个arthas server注册到arthas tunnel server上,每个arthas server都会得到一个agentId,然后arthas tunnel client可以通过该agentId连接到对应的arthas server上。
下载:https://github.com/alibaba/arthas/releases
部署:java -jar arthas-tunnel-server.jar
启动后默认监听8080和7777端口,arthas server通过7777端口注册自己到arthas tunnel server上,可以指定服务端口,和agent注册端口。arthas server启动注册时还可以指定agentId,否则随机生成

启动arthas server
方式一:外部启动
启动arthas server,指定注册地址,指定应用名称
java -jar arthas-boot.jar --telnet-port 9998 --http-port 9999 --tunnel-server 'ws://127.0.0.1:7777/ws' --app-name demoapp
--telnet-port :指定telnet端口(默认3658)
--http-port:指定http端口(默认3658)
--tunnel-server:指定tunnel server地址
--app-name:指定应用名称
启动和注册成功后,arthas tunnel server的管理界面输入agentId连接,即可进入对应的WebConsole命令窗口。

方式二:在SpringBoot项目中集成和启动
pom中引入依赖
<dependency>
<groupId>com.taobao.arthas</groupId>
<artifactId>arthas-spring-boot-starter</artifactId>
<version>3.4.6</version>
</dependency>
application.properties中配置参数
#agentId
arthas.agent-id=hsehdfsfghhwertyfad
#注册地址/tunnel server地址
arthas.tunnel-server=ws://127.0.0.1:7777/ws
#app名称
arthas.app-name=arthas-demo-2
#http端口
arthas.http-port=9998
#telnet端口
arthas.telnet-port=9999
启动项目
项目启动后,在arthas tunnel server端输入agentId连接后即可访问
方式三:以Java Agent方式启动
java -javaagent:/tmp/test/arthas-agent.jar -jar myJavaApp.jar
myJavaApp.jar是目标java程序
arthas高级使用
arthas模块调用图
总共6个模块,包含了arthas的全部功能,总大小12M

arthas高级特性
WebConsole
在浏览器通过WebSocket连接服务端,进行远程操作。服务端可以是arthas server或arthas tunnel server,连接arthas server时需要知道其ip和端口,连接arthas tunnel server时需要知道目标tunnel server的agentId。
HttpAPI
HttpApi是一种用户使能行为,方便用户基于arthas的能力做出个性化的,符合用户自身需求的产品。
Http API 提供类似RESTful的交互接口,请求和响应均为JSON格式的数据。相对于Telnet/WebConsole的输出非结构化文本数据,Http API可以<font color=red>提供结构化的数据</font>,支持更复杂的交互功能,比如特定应用场景的一系列诊断操作。
请求数据格式
{
"action": "exec",
"requestId": "req112",
"sessionId": "94766d3c-8b39-42d3-8596-98aee3ccbefb",
"consumerId": "955dbd1325334a84972b0f3ac19de4f7_2",
"command": "version",
"execTimeout": "10000"
}
所支持的action
-
exec: 同步执行命令,命令正常结束或者超时后中断命令执行后返回命令的执行结果。 -
async_exec: 异步执行命令,立即返回命令的调度结果,命令执行结果通过pull_results获取。 -
interrupt_job: 中断会话当前的命令,类似TelnetCtrl + c的功能。 -
pull_results: 获取异步执行的命令的结果,以http 长轮询(long-polling)方式重复执行 -
init_session: 创建会话 -
join_session: 加入会话,用于支持多人共享同一个Arthas会话 -
close_session: 关闭会话
Profiler和火焰图
Profiler通过不断采样,然后把收集到的采样结果生成火焰图。
下载Profiler
下载地址:https://github.com/jvm-profiling-tools/async-profiler
每种运行环境支持的Profiler不同,比如Mac、Linux、Windows支持的Profiler只不同的
开始采样
profiler start
停止采样和生成svg图片
profiler stop --file /arthas-output/output.svg
在浏览器查看
以下是对CPU采样后生成的火焰图。一列box代表一个stack trace,每个box代表一个stack frame;y轴显示了栈的深度,按照调用关系从下到上排列;x轴代表了整个采样的范围,注意x轴并不代表时间;box的宽度代表了该方法在采样中出现的频率;
不同的采样方式,生成的火焰图的解读是不同的。

命令列表
经典案例
案例一:CPU负载过高
我们可能会遇到这样的问题,用户流量也不是很大,CPU总能飙到很高,导致服务响应变慢。
以前遇到类似的问题,可能会考虑使用top指令加jstack指令取排查,但有效信息还是太少了,多数时候还是要靠猜。但现在我们使用arthas可以更高效更精准的定位问题。
CPU负载过高一般是某个或某几个线程有问题,所以我们尝试使用第一个命令:thread,这个命令会显示所有线程的信息,并且把CPU使用率高的线程排在前面。

可以看到,第一个线程CPU占用率达到92%,它在疯狂的计算,我们认为它很可能在循环调用或存在死循环。那它们究竟在干什么呢?我们可以使用命令:thread id,查看线程堆栈。

在堆栈信息中可以看到属于我们业务代码的类的路径和方法,它在调用MathUtil类的calSum方法;此时我们多执行几次thread指令,发现它的CPU占用率持续飙高,我们猜想里面发生了循环调用或者存在死循环。现在我们使用tt -t com.example.arthas.MathUtil calSum -n 100指令,记录该方法的100次执行情况。

发现100条记录瞬间打满,说明该方法正在被连续调用,tt 命令会记录方法调用时的所有入参和返回值、抛出的异常、对象本身等数据。INDEX字段代表着一次调用,后续tt还有很多命令都是基于此编号指定记录操作。
现在我们通过jad指令反编译一下该方法,发现里面存在死循环。

tt指令结合OGNL表达式重放方法执行过程
