0%

Arthas 详解

Arthas 是 Alibaba 在 2018 年 9 月开源的 Java 诊断 工具。支持 JDK6+, 采用命令行交互模式,可以方便的定位和诊断线上程序运行问题。Arthas 官方文档十分详细,详见:https://arthas.aliyun.com/doc/

Arthas 使用场景

  1. 提供全局视角查看系统的运行状况
  2. 监控 CPU 运行状态
  3. 监控线程运行状态
  4. 监测程序运行耗时
  5. 产科指定类从哪个 jar 包加载的
  6. 反编译线上环境代码,验证 commit 是否生效
  7. 遇到问题在线上 debug 无需通过加日志再重新发布
  8. 监控 JVM 的实时运行状态

Arthas 使用

下载

从 Maven 仓库下载

最新版本,点击下载:

1
wget https://arthas.aliyun.com/download/latest_version?mirror=aliyun -O arthas-packaging-bin.zip

从 Github Releases 页下载

https://github.com/alibaba/arthas/releases

启动

首先解压下载的压缩包

使用 as.sh 启动

在文件夹里有 as.sh,直接用./as.sh 的方式启动:

1
./as.sh

打印帮助信息:

1
./as.sh -h

用 arthas-boot 启动

在文件夹里有 arthas-boot.jar,直接用java -jar 的方式启动:

1
java -jar arthas-boot.jar

打印帮助信息:

1
java -jar arthas-boot.jar -h

下载离线文档

下载文档

使用示例

Arthas 测试程序,代码见下方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import java.util.HashSet;

public class ArthasDemo {

private static HashSet hashSet = new HashSet();

public static void main(String[] args) {
// 模拟 CPU 过高
cpuHigh();
// 模拟线程死锁
deadThread();
// 不断的向 hashSet 集合增加数据
addHashSetThread();
}

/**
* 不断的向 hashSet 集合添加数据
*/
public static void addHashSetThread() {
// 初始化常量
new Thread(() -> {
int count = 0;
while (true) {
try {
hashSet.add("count" + count);
Thread.sleep(1000);
count++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}

public static void cpuHigh() {
new Thread(() -> {
while (true) {

}
}).start();
}

/**
* 死锁
*/
private static void deadThread() {
/** 创建资源 */
Object resourceA = new Object();
Object resourceB = new Object();
// 创建线程
Thread threadA = new Thread(() -> {
synchronized (resourceA) {
System.out.println(Thread.currentThread() + " get ResourceA");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resourceB");
synchronized (resourceB) {
System.out.println(Thread.currentThread() + " get resourceB");
}
}
});

Thread threadB = new Thread(() -> {
synchronized (resourceB) {
System.out.println(Thread.currentThread() + " get ResourceB");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resourceA");
synchronized (resourceA) {
System.out.println(Thread.currentThread() + " get resourceA");
}
}
});
threadA.start();
threadB.start();
}
}

选择进程序号 1,进入进程信息操作

image-20250511161601592

image-20250511161635469

输入 dashboard 可以查看整个进程的运行情况,线程、内存、GC、运行环境信息:

image-20250511161706675

输入 thread 可以查看线程详细情况

image-20250511161724180

输入 thread 加上线程 ID 可以查看线程堆栈

image-20250511161809969

输入 thread -b 可以查看线程死锁

image-20250511161849139

输入 jad 加类的全名 可以反编译,这样可以方便我们查看线上代码是否是正确的版本

image-20250511162108472

使用 ognl 命令可以获取静态变量或修改静态变量

image-20250511162234019

image-20250511162332940

更多命令使用可以用 help 命令查看,或查看文档https://arthas.aliyun.com/doc/commands.html