Arthas(阿尔萨斯)是阿里巴巴开源的一款 Java 诊断工具 ,它可以帮助开发者在 不修改代码、不重启服务 的前提下,对运行中的 Java 应用进行实时诊断、调试、监控和问题排查。
下面我会从你关心的两个层面来讲解 Arthas 提供的机制,并提供简单、全面、便于上手的例子:
一、Arthas 提供的核心机制(功能)
1. 实时查看 JVM 信息
- 查看线程状态(
thread) - 查看内存使用(
memory) - 查看系统属性、类加载器等(
sysprop、sysenv、classloader)
✅ 举例:
thread -n 3查看 CPU 占用最高的 3 个线程堆栈
2. 动态监控方法调用(核心功能)
trace:追踪方法内部调用路径和耗时watch:观察方法参数、返回值、异常monitor:统计方法调用次数和耗时tt(TimeTunnel):记录方法历史调用,可回放
✅ 举例:
bash
watch com.example.service.UserService getUser "params, returnObj" -x 3
监控 getUser 方法的入参和返回值,对象展开 3 层。
3. 动态修改运行时行为(高级调试)
ognl:执行任意 OGNL 表达式(比如调用静态方法、修改静态变量)redefine/retransform:热更新字节码(需配合外部 class 文件)
✅ 举例:
bash
ognl '@com.example.Config@ENABLE_DEBUG=true'
动态开启某个配置开关。
4. 反编译运行中的类
jad:反编译指定类,查看实际加载的字节码对应的源码(尤其用于排查 AOP、代理、Lombok 生成代码)
✅ 举例:
bash
jad com.example.service.UserService
5. 在线诊断 & 火焰图
- 集成 async-profiler,生成火焰图(
profiler start) - 查看热点方法、CPU 瓶颈
二、Arthas IDEA 插件(Arthas Plugin)
功能目标:
让开发者在 IDEA 中直接生成 Arthas 命令,无需手敲复杂语法。
提供机制:
- 右键生成命令
- 在方法上右键 →
Arthas→Watch / Trace / Monitor→ 自动生成命令
- 在方法上右键 →
- 命令预览与复制
- 自动填充类名、方法名、参数表达式
- 与远程 Arthas 控制台联动(需手动粘贴执行)
📌 注意:IDEA 插件 不直接连接 Arthas,它只是"命令生成器"。实际执行仍需在终端 attach 到目标进程。
安装方式:
- 打开 IDEA →
Settings→Plugins→ 搜索 Arthas IDEA → 安装并重启
三、一个完整的小例子(热更新配置 + 监控)
假设你有一个动态配置类:
java
@Component
public class DynamicConfig {
public volatile boolean enableSqlLog = false;
}
使用 Arthas 动态开启 SQL 日志:
-
启动应用,记下 PID(比如 12345)
-
启动 Arthas:
bashjava -jar arthas-boot.jar 12345 -
执行 OGNL 修改配置:
bashognl '#config=@com.example.DynamicConfig@com.example.DynamicConfig, #config.enableSqlLog=true'(实际需根据 Spring 获取 bean 的方式调整,也可通过 Spring Context 获取)
-
用
watch验证是否生效:bashwatch com.example.mapper.UserMapper selectById '{params, #config.enableSqlLog}' -v
四、适用场景总结
| 场景 | Arthas 机制 |
|---|---|
| 线上 CPU 100% | thread -n 5 + profiler |
| 方法返回值不对 | watch |
| 想知道方法哪一步慢 | trace |
| 怀疑 Lombok 生成有问题 | jad 反编译 |
| 想动态开启调试开关 | ognl 修改 static/field |
| 不想重启改日志级别 | 结合 ognl + 日志框架配置类 |
五、注意事项
- 生产环境慎用 :
redefine、ognl修改状态可能带来副作用。 - 需 Java agent 权限:部分环境(如 Docker、K8s)需开放 attach 权限。
- 不支持 JDK 21+ 的某些新特性(截至 Arthas 3.7.x)。
为什么设计出来
!我们来从 设计初衷、监控目标、监控机制、实战 Demo 四个层面,深入浅出地讲清楚 Arthas 为什么被设计出来,以及它是如何工作的。
一、为什么设计 Arthas?------ 起源与痛点
在 线上生产环境 中,Java 应用一旦部署,通常:
- 不能停机(高可用要求)
- 不能随意加日志(日志膨胀、性能影响)
- 不能远程 Debug(安全限制、网络隔离)
但开发者又经常遇到:
- "为什么这个接口突然变慢了?"
- "这个方法到底有没有被调用?"
- "传入的参数是不是有问题?"
- "Lombok 生成的代码到底长什么样?"
传统方式要么 重启加日志 ,要么 抓线程栈+猜,效率极低。
🎯 Arthas 的设计目标 :
在不重启、不修改代码、不侵入业务的前提下,对运行中的 JVM 应用进行实时观测与诊断。
它本质上是一个 JVM 诊断代理(Java Agent) ,利用 Instrumentation + ASM + OGNL 等技术,在运行时动态注入监控逻辑。
二、有什么东西要监控?------ 常见监控目标
| 监控维度 | 具体内容 | Arthas 命令 |
|---|---|---|
| 线程 | CPU 飙高?死锁?阻塞? | thread |
| 内存 | 堆内存、GC 情况 | memory, gc |
| 方法调用 | 谁调了我?参数对吗?耗时多少?返回值是什么? | watch, trace, monitor, tt |
| 类加载 | 类是否加载?从哪个 ClassLoader? | classloader, sc |
| 源码结构 | 实际运行的字节码对应的源码(含代理、Lombok) | jad |
| 执行表达式 | 动态修改配置、调用方法 | ognl |
| 性能分析 | 热点函数、CPU 火焰图 | profiler |
三、怎么监控?------ 核心机制简述
Arthas 通过 Java Agent 机制 attach 到目标 JVM 进程,然后:
-
动态增强(Instrumentation)
使用 ASM 修改目标类的字节码,在方法入口/出口插入监控代码(比如记录参数、时间、返回值)。
-
表达式求值(OGNL)
支持在运行时执行任意表达式,访问/修改任意字段、调用方法。
-
交互式命令行
提供 telnet/WebConsole 交互界面,实时下发指令。
✅ 举个比喻:
Arthas 就像给运行中的 Java 程序装了一个"内窥镜 + 遥控器"------既能看内部状态,又能临时调控。
四、实战 Demo ------ 5 分钟上手
我们模拟一个典型场景:线上接口突然变慢,但本地无法复现。
步骤 1:准备一个 Spring Boot 示例应用
java
@RestController
public class DemoController {
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
// 模拟耗时操作
try {
Thread.sleep(id * 10); // id 越大越慢
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return new User(id, "user-" + id);
}
}
record User(Long id, String name) {}
启动后,访问 http://localhost:8080/user/100 会明显变慢。
步骤 2:启动 Arthas
bash
# 下载 arthas-boot.jar(只需一次)
curl -O https://arthas.aliyun.com/arthas-boot.jar
# 假设你的 Spring Boot PID 是 12345
java -jar arthas-boot.jar 12345
选择你的应用进程,进入 Arthas 控制台。
步骤 3:监控方法调用(核心 Demo)
🎯 目标 1:看谁在调用 getUser,参数是什么?
bash
watch com.example.demo.DemoController getUser "{params[0], returnObj}" -x 2
访问 /user/200,Arthas 输出:
ts=2025-12-25 17:30:00; [cost=2008ms]
@Object[][
@Long[200],
@User[
id=@Long[200],
name=@String[user-200]
]
]
✅ 一眼看出:传入 id=200,耗时 2008ms,返回对象完整结构。
🎯 目标 2:追踪耗时在哪?
bash
trace com.example.demo.DemoController getUser
输出:
`---ts=2025-12-25 17:31:00; [cost=2005ms]
`---com.example.demo.DemoController.getUser() [2005ms]
`---java.lang.Thread.sleep(Native Method) [2000ms]
✅ 明确看到:99% 时间花在 Thread.sleep 上!
🎯 目标 3:动态修改行为(临时修复)
假设我们想临时禁止大 ID 访问(比如 id > 100),但又不能改代码。
先用 jad 看源码(确认类名):
bash
jad com.example.demo.DemoController
然后通过 OGNL 注入逻辑(需结合 Spring Context,简化版):
实际中可通过
ognl获取 Spring Bean 并修改其内部状态,或配合 AOP 拦截。
(此处略复杂,但说明:Arthas 能让你"动态编程")
步骤 4:退出 & 清理
bash
stop # 退出 Arthas,不影响原应用
原应用继续运行,无任何侵入。
五、总结:Arthas 的核心价值
| 传统方式 | Arthas 方式 |
|---|---|
| 加日志 → 重启 → 复现 → 查日志 | 直接 attach,实时 watch |
| jstack 看线程,猜问题 | thread -b 直接找死锁 |
| 反编译 jar 看源码 | jad 直接看运行时类 |
| 无法知道方法内部调用链 | trace 一键输出耗时链路 |
💡 Arthas 不是监控系统(如 Prometheus),而是"在线 Debugger + Profiler"。
如果你正在用 Spring Boot + MyBatis + Redis,Arthas 还能:
watchMyBatis Mapper 方法,看 SQL 参数traceRedis 操作,查连接超时ognl动态开关 MyBatis 二级缓存