Arthas Java 诊断工具实战手册
约 1509 字大约 5 分钟
2025-06-20
Arthas 是阿里巴巴开源的 Java 诊断工具,让你无需重启 JVM 就能排查线上问题、监控方法调用、反编译代码。
背景与动机
在 Java 应用开发中,你是否遇到过这些问题:
- 线上出现异常,但无法复现,想知道方法调用的入参和返回值?
- 怀疑某个方法有性能问题,但无法确定具体耗时?
- 需要查看运行中的代码逻辑,但没有源码?
- 想修改一行代码验证猜想,但重启应用代价太大?
Arthas 就是解决这些问题的利器。它通过字节码增强技术,在不重启 JVM 的情况下实现:
- 方法调用监控
- 异常捕获
- 代码热更新
- 性能分析
安装与启动
快速安装
# 下载 arthas-boot.jar
curl -O https://arthas.aliyun.com/arthas-boot.jar
# 启动并选择 Java 进程
java -jar arthas-boot.jar启动后会列出当前机器上所有 Java 进程,输入编号即可 attach 到目标进程。
常见启动问题
如果遇到 Unable to get java version 或 Can not attach to process:
# 检查 Java 版本
java -version
# 确保有权限 attach(JDK 9+ 需要添加 JVM 参数)
# -Djdk.attach.allowAttachSelf=true核心命令详解
watch - 方法调用监控
watch 命令用于观察方法的入参、返回值、异常等信息。
基本语法:
watch 类全限定名 方法名 "表达式" 条件选项常用表达式:
| 表达式 | 说明 |
|---|---|
params | 方法入参数组 |
returnObj | 返回值 |
throwExp | 抛出的异常 |
target | 当前对象 |
#cost | 方法执行耗时(ms) |
实战示例:
监控方法入参和返回值:
watch com.example.UserService getUser "{params, returnObj}" -x 2只监控耗时超过 100ms 的调用:
watch com.example.UserService getUser "{params, #cost}" "#cost>100" -x 2监控抛出异常的调用:
watch com.example.UserService getUser "{params, throwExp}" "throwExp!=null" -e -x 2tt - 时空隧道
tt 命令记录方法调用的完整现场,支持事后回放。
记录方法调用:
# 记录最近 5 次调用,只记录抛出异常的情况
tt -t com.example.UserService getUser -n 5 'throwExp!=null'查看记录详情:
# 列出所有记录
tt -l
# 查看具体记录(1000 是记录的 INDEX)
tt -i 1000
# 查看记录的入参和返回值
tt -i 1000 -w "{params, returnObj}"回放调用:
# 使用记录的入参重新调用方法
tt -i 1000 -ptt 的优势在于记录了完整现场,即使问题已经过去,仍能通过索引查看详情。
jad - 反编译代码
jad 命令反编译 JVM 中加载的类,查看运行中的代码逻辑。
查看源码:
# 只输出源码(不含行号)
jad --source-only com.example.UserService getUser
# 输出完整信息(包含类加载器、源码)
jad com.example.UserService getUser输出到文件:
jad --source-only com.example.UserService > /tmp/UserService.java这在排查线上问题时非常有用,可以确认运行的代码是否与预期一致。
trace - 调用链路追踪
trace 命令追踪方法内部调用链路,定位性能瓶颈。
# 追踪方法内部调用耗时
trace com.example.UserService getUser
# 只追踪耗时超过 50ms 的调用
trace com.example.UserService getUser '#cost > 50'
# 追踪深度限制为 3 层
trace com.example.UserService getUser -n 3输出示例:
`---[12.345ms] com.example.UserService:getUser()
+---[5.123ms] com.example.UserDao:findById()
`---[3.456ms] com.example.CacheService:get()stack - 调用栈追踪
stack 命令查看方法是从哪里被调用的。
stack com.example.UserService getUser输出会显示完整的调用栈,帮助定位方法调用来源。
实战案例
案例 1:捕获线上异常
问题:线上日志有异常堆栈,但缺少关键参数信息。
解决:
# 记录异常发生时的入参
tt -t com.yonyoucloud.fi.epub.service.openbusinessvolumeindexdimension.busiconvert.impl.BusIndexQuantityFieldValueConverterImpl convert -n 5 'throwExp!=null'
# 查看记录详情
tt -i 1000案例 2:查看线上代码逻辑
问题:怀疑线上代码与预期不符,需要确认运行中的代码。
解决:
jad --source-only com.yonyoucloud.fi.epub.service.openbusinessvolumeindexdimension.busiconvert.impl.BusVolumeProOrderLineFieldValueConverterImpl convert案例 3:热更新修复 Bug
问题:临时修复一个 Bug,重启应用代价太大。
解决:
# 1. 反编译源码到文件
jad --source-only com.yonyoucloud.manufacturing.service.bom.BomInsideNewService > /data/BomInsideNewService.java
# 2. 编辑 Java 文件(修复 Bug)
vim /data/BomInsideNewService.java
# 3. 查找类加载器 Hash
sc -d com.yonyoucloud.manufacturing.service.bom.BomInsideNewService | grep classLoaderHash
# 4. 编译生成 class 文件(87f91fd 是类加载器 Hash)
mc -c 87f91fd /data/BomInsideNewService.java -d /data/
# 5. 热更新
redefine /data/com/yonyoucloud/manufacturing/service/bom/BomInsideNewService.class注意:
redefine只能修改方法体,不能修改方法签名、字段、继承关系。重启后修改会丢失。
常见问题
1. attach 失败怎么办?
检查目标进程是否有权限限制:
# JDK 9+ 需要添加 JVM 参数
-Djdk.attach.allowAttachSelf=true2. 如何退出 Arthas?
# 退出当前会话(不影响目标进程)
quit
# 完全停止 Arthas 服务端
stop3. 监控会影响性能吗?
watch、trace 等命令通过字节码增强实现,会有一定性能开销。建议:
- 限制监控条件(如
#cost>100) - 监控完成后及时关闭
- 生产环境谨慎使用
trace(追踪范围广)
4. 如何查看帮助?
# 查看命令帮助
watch -h
tt -h
# 查看所有命令
help常用命令速查
| 命令 | 用途 | 示例 |
|---|---|---|
watch | 方法调用监控 | watch com.example.Service method "{params,returnObj}" |
tt | 记录方法调用现场 | tt -t com.example.Service method -n 5 |
jad | 反编译代码 | jad --source-only com.example.Service |
trace | 调用链路追踪 | trace com.example.Service method |
stack | 查看调用来源 | stack com.example.Service method |
sc | 查看类信息 | sc -d com.example.Service |
sm | 查看方法信息 | sm com.example.Service |
redefine | 热更新代码 | redefine /path/to/Service.class |
ognl | 执行 OGNL 表达式 | ognl '@com.example.Constant@VALUE' |
heapdump | 导出堆内存 | heapdump /tmp/dump.hprof |
总结
Arthas 是 Java 开发者的线上排查利器,核心优势:
- 无需重启:attach 到运行中的 JVM
- 低侵入性:字节码增强,不修改原有代码
- 功能全面:监控、追踪、反编译、热更新
使用建议:
- 生产环境慎用,监控完成后及时退出
- 复杂问题配合
tt记录现场,事后分析 - 热更新仅用于临时验证,正式修复需走发布流程
