Arthas 线上诊断实战

系统讲解 Arthas 线上诊断实战:安装与启动、常用命令速查、dashboard 与 thread 命令、watch 与 trace 方法级观测、jad 反编译与 redefine 热更新、线程与内存排查,以及生产环境的安全使用规范。

线上出问题的时候,最难受的是「代码就在眼前,却看不到运行时」。重启加日志要等下一轮发布,慢方法定位靠猜,堆栈抓了看不懂。Arthas(阿里开源的 Java 诊断工具)让你无需重启、不改代码就能查看运行中的类、方法调用参数、返回值和异常栈,甚至热更新代码。本文从安装讲到命令实战与生产安全。

一、Arthas 是什么:线上诊断瑞士军刀

Arthas 通过 attach 到目标 JVM 进程,基于 Java Instrumentation 和字节码增强,在不改源码、不重启的前提下实现运行时观测与操作。

能力说明
在线观测看方法入参、返回值、异常、耗时
反编译jad 查看运行时真实字节码对应的源码
热更新redefine 用新编译的类替换运行中的类
线程分析thread 查看线程状态与阻塞原因
类加载classloader 查看类加载器与冲突
OGNL直接读取/修改运行时对象属性
Arthas 适用场景:
  生产环境偶发问题,日志不够用
  排查慢接口、死锁、内存异常
  临时热修复(有风险,需走流程)
  排查类冲突、依赖版本问题

一句话总结: Arthas 是「运行中的显微镜 + 手术刀」——不重启、不改代码就能看方法调用、反编译类、热更新代码,是线上排障的第一梯队工具。


二、安装与启动

2.1 快速开始

# 下载 arthas-boot,或用包管理工具
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

# 交互选择要 attach 的 Java 进程,或直接指定 PID
java -jar arthas-boot.jar <pid>

# 也可以作为服务启动,支持远程连接
java -jar arthas-as-service.jar

2.2 基本交互

进入 Arthas 交互界面后:
  help        查看所有命令
  quit        退出(不影响目标进程)
  session     查看当前会话信息
  reset       重置所有增强过的类(恢复原始字节码)
  shutdown    关闭 Arthas 服务端
# 非交互方式:attach 后执行单条命令即退出
java -jar arthas-boot.jar --attach-only <pid>
# 或通过 telnet/HTTP 接口脚本化调用

一句话总结: Arthas 用 java -jar arthas-boot.jar <pid> 即可 attach;掌握 reset、quit、shutdown 三个命令是生产环境「全身而退」的前提。


三、常用命令速查

3.1 dashboard 与 thread

# 仪表盘:实时显示 CPU、内存、GC、线程概览
dashboard

# 查看所有线程及状态
thread

# 找出 CPU 占用最高的线程(Top 20)
thread -n 20

# 查看某个线程的完整堆栈
thread <threadId>

# 查看线程是否阻塞、等什么锁
thread -b
thread -b 输出解读:
  如果有输出 → 找到了持锁线程,是死锁/锁等待的元凶
  输出为空   → 没有线程在阻塞,问题可能是 IO 或 CPU 忙

3.2 watch 与 trace

# watch:观测方法调用的入参、返回、异常
watch com.example.OrderService placeOrder '{params, returnObj, throwExp}' -x 3

# trace:跟踪方法内部每一层的耗时
trace com.example.OrderService placeOrder

# 带条件观测:只有耗时超过 200ms 才打印
watch com.example.OrderService placeOrder '{params[0].userId}' '#cost > 200'
参数含义
-n观测次数上限
-x展开对象深度
#cost本次调用耗时(ms)
-e只观测异常
-f是否观测方法执行结束

一句话总结: 核心三板斧——dashboard 看全局、thread 查线程、watch/trace 钻方法;thread -b 找持锁线程、#cost 过滤慢调用是最常用的两个组合。


四、jad 反编译与 redefine 热更新

4.1 jad 反编译运行时类

# 查看线上真实运行的类源码(含行号)
jad com.example.OrderServiceImpl

# 只反编译某个方法
jad --source-only com.example.OrderServiceImpl placeOrder

# 定位类是从哪个 jar 加载的
sc -d com.example.OrderServiceImpl
jad 的价值:
  1. 确认线上跑的到底是哪个版本的代码
  2. 看字节码增强后的真实逻辑(是否有代理/包装)
  3. 排查反编译结果与源码不一致 → 版本漂移

4.2 mc 与 redefine 热更新

# 1. 本地编译新代码
mc /tmp/Fix.java -d /tmp/out

# 2. 用编译产物替换运行中的类
redefine -c <classloaderHash> /tmp/out/com/example/Fix.class

# 3. 验证增强
jad com.example.Fix
// 一个临时修复的例子:原代码返回空导致 NPE
public class Fix {
    public static String getConfig(String key) {
        return "default_value";   // 临时兜底值
    }
}

一句话总结: jad 确认「线上到底跑的什么代码」,mc + redefine 提供临时热修复能力;但热更新只改变内存中的类,重启即失效,必须同时排期正式发布。


五、线程与内存排查

5.1 线程问题排查

# 高 CPU 定位:先找最耗 CPU 的线程,再看它的栈
thread -n 10

# 死锁检测
thread -b

# 锁竞争观察:配合 watch 看锁等待耗时
watch java.util.concurrent.locks.ReentrantLock lock '{params[0]}' -n 5

5.2 内存相关排查

# 查看堆使用概况
memory

# 查看 GC 情况
gc

# 查看类加载器及加载的类数量
classloader

# 查看某个类的实例数量与大小(需要开启)
# vmtool --action getInstances --className com.example.Cache --limit 100
Arthas 与堆转储的配合:
  Arthas 适合快速看对象实例、类加载、GC 状态
  大堆对象 / 引用链分析还是用 MAT 更全面
  先用 Arthas 缩小范围,再 dump 给 MAT 深挖

一句话总结: 线程排查靠 thread -n、thread -b,内存排查靠 memory、gc、vmtool 看实例;Arthas 快速缩小范围,MAT 深挖引用链是高效的组合。


六、方法调用链与 OGNL

6.1 trace 定位慢方法

# 一层层展开,找到耗时子方法
trace -n 3 com.example.OrderService placeOrder '#cost > 100'

# 同时观测多个方法
trace com.example.OrderService placeOrder com.example.InventoryService checkStock
trace 输出解读:
  每一行是一个子方法调用,右侧是耗时
  看占比最大的子调用,就是慢的根源
  继续对慢子方法再 trace,逐层下钻

6.2 OGNL 读取与修改变量

# 读取静态字段
ognl '@com.example.Config@INSTANCE.timeout'

# 调用方法
ognl '@java.lang.System@getProperty("user.dir")'

# 修改静态字段(谨慎!)
ognl -x 3 '@com.example.Config@INSTANCE.timeout = 5000'
OGNL 的边界:
  能读:静态字段、对象属性、方法返回值
  能改:静态字段、属性(慎用,影响所有线程)
  不能:修改方法字节码、新增字段

一句话总结: trace 逐层下钻把「慢在哪一层」可视化;ognl 直接操作运行时对象——读安全、改要慎,改静态配置时务必评估全局影响。


七、生产安全与权限

7.1 风险评估

操作风险管控建议
watch/trace低,有性能开销加 -n 限制次数,观测后 reset
jad/sc低,只读无特殊限制
ognl 修改中,影响全局只允许读,修改需审批
redefine 热更新高,改运行代码必须走变更流程 + 留痕 + 回滚预案
日志敏感信息中,可能泄露watch 表达式过滤敏感字段

7.2 安全规范

生产环境 Arthas 使用规范:
  1. 仅在低峰期、白名单机器使用
  2. 观测命令必须带 -n 限制,防止无限输出
  3. 用完立即 reset / quit,不留增强字节码
  4. 远程访问走安全通道(SSH 隧道 / HTTP 鉴权)
  5. redefine 必须记录变更内容与时间,配套正式发布
# SSH 隧道远程访问 Arthas 的典型姿势
ssh -L 8563:localhost:8563 user@host
# 本地再通过 http://localhost:8563 访问 Arthas WebConsole

一句话总结: Arthas 功能越强大,越要约束使用边界——观测命令限量、修改操作审批、用完即 reset;权限与留痕是线上工具落地的前提。


八、实战陷阱清单

陷阱现象对策
watch 无限输出控制台刷屏、性能劣化加 -n、#cost 条件
忘记 reset增强字节码残留用完立即 reset
redefine 后重启失效修复没生效同时排期正式发布
类加载器冲突jad 找不到类先 classloader 定位正确的 ClassLoader
OGNL 误改全局配置全量行为变化只读为主,修改需审批
高并发下 trace采集开销放大低峰期使用,限制次数
敏感信息打印日志泄露过滤 params 表达式

九、总结

命令用途一句话
dashboard全局状态一眼看 CPU/GC/线程
thread -b死锁定位找出持锁元凶
watch方法观测看入参、返回、异常
trace耗时下钻慢在哪一层
jad反编译线上跑的什么代码
redefine热更新临时修复,重启失效
ognl运行时操作读安全,改要慎

一句话记住:Arthas 把「线上诊断」从「重启+加日志」升级为「即时观测+可控操作」。把它当手术刀而非常规工具:watch 限量、reset 及时、redefine 走流程,就能在关键时刻救急而不惹祸。

延伸阅读

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「java」更多文章

  1. Java 序列化方案对比与性能
  2. Java 并发设计模式实战
  3. OOM 排查与堆转储分析