Arthas(阿尔萨斯) - Java 线上问题定位处理的终极利器

2,577 阅读5分钟

一、Arthas(阿尔萨斯)简介

1.1 什么是Arthas

我们可以通过官网查看Arthas能为你做什么,以下这段话摘自官方:

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

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


Arthas支持JDK 6+,支持Linux/Mac/Winodws,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

1.2 Arthas运行原理

1.3 Arthas 常用命令列表

二、Arthas使用说明

2.1 Arthas 及 demo下载

2.1.1 从github上下载arthas示例

github链接地址:github.com/hhhhax/arth…

2.1.2 启动arthas

在命令行下面执行(使用和目标进程一致的用户启动,否则可能attach失败):

curl -O https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar


选择应用java进程,这里我们启动的是spring-boot-single-demo-1.0.0-SNAPSHOT.jar,所以我们输入3,至此我们已进入Arthas命令界面。

2.2 Arthas常用命令

2.2.1 dashboard

查看当前系统的实时数据面板,按 ctrl+c 退出。当运行在Ali-tomcat时,会显示当前tomcat的实时信息,如HTTP请求的qps, rt, 错误数, 线程池信息等等。

参数说明

参数名称 参数说明
ID Java级别的线程ID,注意这个ID不能跟jstack中的nativeID一一对应
NAME 线程名
GROUP 线程组名
PRIORITY 线程优先级, 1~10之间的数字,越大表示优先级越高
STATE 线程的状态
CPU% 线程消耗的cpu占比,采样100ms,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。
TIME 线程运行总时间,数据格式为分:秒
INTERRUPTED 线程当前的中断位状态
DAEMON 是否是daemon线程

2.2.2 thread

查看当前线程信息,查看线程的堆栈

参数说明

参数名称 参数说明
id 线程id
[n:] 指定最忙的前N个线程并打印堆栈
[b] 找出当前阻塞其他线程的线程
[i ] 指定cpu占比统计的采样间隔,单位为毫秒

使用例子

查看线程ID为1的线程运行堆栈:

这里我们可以结合代码看到线程1运行的是例子中MathGame的方法,此时刚好运行到sleep。

一键展示当前最忙的前N个线程并打印堆栈:

没有参数时打印出所有堆栈信息:

thread -b, 找出当前阻塞其他线程的线程:


有时候我们发现应用卡住了, 通常是由于某个线程拿住了某个锁, 并且其他线程都在等待这把锁造成的。 为了排查这类问题, arthas提供了thread -b, 一键找出那个罪魁祸首。

2.2.3 jad

通过jad来反编译Main Class。

通常用来查看确定线上或者测试环境的包是否是我们修改过的。

2.2.4 watch

通过watch命令来查看MathGame#primeFactors函数的返回值:

2.2.5 jvm

查看当前JVM信息。

2.2.6 mc

Memory Compiler/内存编译器,编译.java文件生成.class。

2.2.7 redefine

该命令可以加载外部的.class文件,然后覆盖 jvm已加载的类。注意,这个命令不一定都能覆盖成功,如果添加了新的field,就不会加载成功。
注:可配合jad和mc一起使用达到线上排查问题而不用重启服务器

2.2.8 monitor

方法执行监控。

monitor 命令是一个非实时返回命令.

实时返回命令是输入之后立即返回,而非实时返回的命令,则是不断的等待目标 Java 进程返回信息,直到用户输入 Ctrl+C 为止。

2.2.9 trace

方法内部调用路径,并输出方法路径上的每个节点上耗时。

注意: trace 能方便的帮助你定位和发现因 RT 高而导致的性能问题缺陷,但其每次只能跟踪一级方法的调用链路。

根据调用耗时过滤

只会展示耗时大于5ms的调用路径,有助于在排查问题的时候,只关注异常情况。

由于trace每次只能跟踪一级调用链路,由上图我们可知时间耗时主要是在findById,因此我们可继续跟踪findById调用链路,如下:

至此我们就能发现该方法大部分耗时都是在处理sql语句,我们可以根据这个对语句进行优化。

注意:watch/stack/trace这个三个命令都支持#cost

三、总结

以上举例了Arthas一些常用的方法,但仅仅是Arthas用途的冰山一角,仅仅起到了抛砖引玉的作用。
要想深入学习Arthas可详细阅读一遍官网文档,github上也有Arthas上实践使用,Arthas官网传送门,github实践用例传送门