告别盲猜:用 Arthas 高效排查 Java 生产问题

157 阅读4分钟

阿里巴巴开源的 Java 诊断利器 —— 在线排查、性能分析、内存诊断,无需重启!

一、为什么需要 Arthas

线上 Java 应用出现问题时,传统方式往往需要:

  • 加日志 → 重新打包 → 发布 → 等待复现 → 查日志

而 Arthas 允许你直接 attach 到运行中的 JVM,实时观测线程、方法、内存、类加载状态,甚至动态追踪调用链,秒级定位问题根源


二、核心能力与原理简述

Arthas 基于 JVM Attach + Instrumentation + ASM 字节码增强 实现,无需预埋代码,支持:

  • 🔍 实时监控线程、内存、GC
  • 🕵️ 追踪方法入参、返回值、耗时
  • 📊 生成火焰图、堆转储分析
  • 🧪 执行任意 Java 表达式(OGNL)
  • 🛠️ 动态修改运行逻辑(谨慎使用)

⚠️ 注意:Arthas 是交互式诊断工具,不是 APM(如 SkyWalking),适用于深度排查具体问题

三、常用命令全景图(按诊断流程排序)

阶段命令用途使用频率
1. 全局概览dashboard实时显示 CPU、内存、线程、GC 状态⭐⭐⭐⭐⭐
thread查看线程(-n 5 显示 Top CPU)⭐⭐⭐⭐⭐
2. 类与代码确认sc搜索已加载的类⭐⭐⭐
jad反编译类,确认线上代码版本⭐⭐⭐⭐
3. 方法行为观测watch监控方法入参/返回值/异常⭐⭐⭐⭐
trace追踪方法内部调用链及耗时⭐⭐⭐⭐
monitor统计方法 QPS、成功率、平均耗时⭐⭐⭐
4. 性能剖析profiler生成 CPU/内存火焰图(需 async-profiler)⭐⭐⭐
5. 内存诊断heapdump导出堆内存快照(用于 MAT 分析)⭐⭐⭐⭐
vmtool强制 GC、查看对象实例数量⭐⭐
6. 表达式执行ognl在沙箱中执行任意 Java 表达式⭐⭐⭐

💡 建议流程dashboard → thread → sc/jad → watch/trace → heapdump/profiler

四、生产问题排查实战

场景 1:CPU 飙高,定位热点线程

🔍 现象

服务器 CPU 持续 100%,应用响应缓慢。

🛠️ 排查流程

# 1. 查看系统概览
dashboard

# 2. 找出 CPU 占用最高的 3 个线程
thread -n 3

# 3. 打印具体线程堆栈(假设 tid=57)
thread 57

# 4. 反编译问题类确认逻辑
jad com.example.util.InfiniteLoop

✅ 关键点thread -n N 按 CPU 使用率排序,快速定位“罪魁祸首”。


场景 2:方法返回异常,但无日志

🔍 现象

用户反馈功能异常,但日志未报错,怀疑参数或逻辑有误。

🛠️ 排查流程

# 1. 监控方法入参和返回值(仅当返回 null 时触发)
watch com.example.service.UserService getUser '{params, returnObj}' 'returnObj == null'

# 2. 若想捕获异常
watch com.example.service.UserService getUser '{params, throwExp}' 'throwExp != null'

# 3. 深入内部调用链(耗时 > 100ms 时打印)
trace com.example.service.UserService getUser '#cost > 100'

✅ 技巧watch 支持 OGNL 条件过滤,避免海量输出。

场景 3:内存溢出(OOM)或内存泄漏

🔍 现象

应用频繁 Full GC,老年代内存持续增长,最终 OOM。

🛠️ 排查流程

graph TD
    A[内存持续增长] --> B[dashboard 查看 Old Gen]
    B --> C[vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --limit 10 com.example.model.CacheObject]
    C --> D{对象是否异常堆积?}
    D -- 是 --> E[heapdump 导出分析]
    D -- 否 --> F[profiler 分析内存分配]

📌 关键命令

# 1. 查看内存概览
dashboard

# 2. 统计某类实例数量(需指定类加载器)
vmtool --action getInstances \
       --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader \
       --limit 10 \
       com.example.model.UserCache

# 3. 导出堆转储(供 MAT/Eclipse 分析)
heapdump /tmp/heap.hprof

# 4. (可选)启动内存分配采样
profiler start --event alloc
# ... 等待 30s ...
profiler stop --format html

✅ 注意

  • Spring Boot Fat Jar 需指定 LaunchedURLClassLoader
  • heapdump 会暂停应用(STW),避开高峰期执行

场景 4:类找不到(ClassNotFoundException / NoClassDefFoundError)

🔍 现象

运行时报 ClassNotFoundException: com.mysql.cj.jdbc.Driver,但依赖已引入。

🛠️ 排查流程

# 1. 搜索是否加载了该类
sc *Driver

# 2. 查看类加载信息(确认加载器)
sc -d com.mysql.cj.jdbc.Driver

# 3. 检查类路径(通过 OGNL)
ognl '@java.lang.System@getProperty("java.class.path")'

✅ 常见原因

  • 依赖冲突(多个版本)
  • 类被错误的 ClassLoader 加载
  • Fat Jar 中路径不正确

场景 5:动态验证配置或开关效果

🔍 现象

想确认某个 Feature Flag 是否生效,或配置中心参数是否更新。

🛠️ 排查流程

# 1. 执行表达式读取配置
ognl '@com.example.config.AppConfig@getInstance().isEnableNewFeature()'

# 2. 调用静态方法触发刷新
ognl '@com.example.service.ConfigManager@refresh()'

# 3. 验证结果
ognl '@com.example.service.FeatureService@isEnabled("NEW_UI")'

✅ 优势:无需重启,立即验证配置变更效果。


五、生产使用注意事项

🔒 安全规范

  • 禁止公网暴露:Arthas 默认仅监听 127.0.0.1,远程访问必须通过 SSH 隧道
  • 权限最小化:仅授权给核心运维/SRE
  • 操作审计:建议记录 Arthas 操作日志(可通过 script 命令录制)

⚠️ 性能影响

  • watch / trace 会显著降低目标方法性能(因字节码增强),排查完立即 reset
  • heapdump 会触发 Full GC 并暂停应用,务必在低峰期执行

🛠️ 最佳实践

  1. 预发演练:复杂命令先在测试环境验证
  2. 组合使用jad + watch + trace 形成完整证据链
  3. 自动化脚本:对高频问题编写 .arthas 脚本,一键执行

六、总结

Arthas = Java 工程师的“X光机 + 示波器”

  • ✅ 适用场景

    • CPU/内存异常
    • 方法行为异常
    • 类加载问题
    • 动态配置验证
  • ❌ 不适用场景

    • 全链路追踪(用 SkyWalking/Pinpoint)
    • 长期监控(用 Prometheus + Grafana)

📌 记住
线上问题,先 attach Arthas,再猜原因!

安装

curl -O https://arthas.aliyun.com/arthas-boot.jar

java -jar arthas-boot.jar

如果下载速度比较慢,可以使用 aliyun 的镜像:

java -jar arthas-boot.jar --repo-mirror aliyun --use-http

使用as.sh

curl -L https://arthas.aliyun.com/install.sh | sh

IDEA建议安装

arthas idea 插件 便于生成Arthas命令

image.png