Skip to content
第 77 / 250 章后端⏱ 10 分钟阅读

第 77 章:Arthas 与线上诊断

学习目标

  • 掌握 Arthas 常用命令排查线上问题
  • 学会热更新代码、监控方法耗时、查看调用栈
  • 理解 JVM 调优基础

一、为什么需要 Arthas?

场景

  • 线上接口突然慢了,怎么定位是哪个方法慢?
  • 怀疑某个方法有 bug,但日志没打,怎么在线查看参数?
  • 紧急 bug 需要修复,但发布要半小时,能不能热更新?
  • JVM 内存高,怎么看是谁占用了?

Arthas(阿尔萨斯)是阿里开源的 Java 诊断工具,无需重启 JVM,在线诊断。

bash
# 安装(Linux/Mac)
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

# Windows
java -jar arthas-boot.jar

启动后选择要诊断的 Java 进程,进入交互式命令行。

二、dashboard:全局看板

bash
dashboard

关键指标

  • Heap 内存:used / total / max
  • GC 次数:年轻代 / 老年代
  • 线程数:RUNNABLE / TIMED_WAITING / BLOCKED
  • 系统:CPU 负载、内存使用率

三、thread:线程分析

查最忙的线程

bash
thread -n 3            # CPU 占用最高的 3 个线程

输出:

ID    NAME                          STATE      %CPU
22    http-nio-8080-exec-5          RUNNABLE   8.3%
25    http-nio-8080-exec-8          RUNNABLE   5.1%
31    scheduling-1                  TIMED_WAIT 0.2%

看线程栈

bash
thread 22              # 查看 22 号线程的栈
thread -b              # 查看 BLOCKED 的线程(找死锁)
thread -w {threadId}  # 等待指定线程结束
java
// 输出示例:
"http-nio-8080-exec-5" #22 daemon prio=5 tid=0x00007f...
   java.lang.Thread.State: RUNNABLE
    at com.taskflow.service.OrderService.queryOrder(OrderService.java:42)
    at com.taskflow.controller.OrderController.list(OrderController.java:30)
    ...

实战:监控到 BLOCKED 线程数突然飙升 → 怀疑死锁或锁竞争。

四、watch:观察方法调用

bash
# 监控 OrderService.createOrder 方法的入参和返回值
watch com.taskflow.service.OrderServiceImpl createOrder \
     "{params, returnObj, throwExp, cost}" \
     -x 5
参数含义
params入参(数组)
returnObj返回值
throwExp异常
cost耗时(ms)
-x展开对象层级

实战:监控慢方法

bash
# 监控所有调用,耗时超过 200ms 的
watch com.taskflow.service.OrderService * \
     "{params, returnObj, throwExp, cost}" \
     '#cost > 200' \
     -x 5

实战:监控特定参数

bash
# 只监控 userId=1001 的调用
watch com.taskflow.service.UserService getById \
     "{params[0], returnObj}" \
     'params[0] == 1001'

五、trace:方法调用路径

bash
# 追踪 queryOrder 方法的完整调用链
trace com.taskflow.service.OrderService queryOrder \
      '#cost > 100' \
      -n 5

输出:

`---ts=2026-08-12 14:23:45;thread_name=http-nio-exec-3;id=23;is_daemon=true;priority=5;TCCL=...
    `---[245.231ms] com.taskflow.service.OrderService:queryOrder()
        +---[180.123ms] com.taskflow.mapper.OrderMapper:selectList()
        |   `---[175.012ms] org.mybatis:selectList()
        +---[ 35.220ms] com.taskflow.service.UserService:getById()
        |   `---[ 30.112ms] com.taskflow.mapper.UserMapper:selectById()
        `---[ 25.432ms] com.taskflow.service.InventoryService:checkStock()

一眼看出:selectList 用了 180ms,是性能瓶颈。

trace vs monitor

  • trace 看完整调用链(深度)
  • monitor 看方法统计(广度)

六、monitor:方法统计

bash
# 每 5 秒统计一次方法调用情况
monitor com.taskflow.service.OrderService createOrder -c 5

输出:

 timestamp            class                          method        total  success  fail  avg-rt(ms)  fail-rate
 2026-08-12 14:25:00  com.taskflow.service.OrderService  createOrder  1234    1230    4    12.34       0.32%
 2026-08-12 14:25:05  com.taskflow.service.OrderService  createOrder  1189    1189    0    11.23       0.00%

关键指标

  • avg-rt:平均响应时间
  • fail-rate:失败率
  • total:调用次数

七、jad:反编译

bash
# 查看线上跑的类源码
jad com.taskflow.service.OrderServiceImpl
bash
# 反编译特定方法
jad com.taskflow.service.OrderServiceImpl createOrder

实战:怀疑线上跑的代码和 Git 不一致(发布出错了)→ 用 jad 反编译确认。

八、sc / sm:查类和方法

bash
# 查加载的类
sc com.taskflow.*   | head -20

# 查类的方法
sm com.taskflow.service.OrderServiceImpl

输出:

com.taskflow.service.OrderServiceImpl
  createOrder(OrderDTO)
  updateOrder(OrderDTO)
  queryOrder(Long)
  deleteOrder(Long)

九、ognl:执行表达式

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

# 查 Spring Bean 的属性
ognl '@com.taskflow.context.SpringContextHolder@getBean("orderServiceImpl").status'

# 查线程数
ognl '@java.lang.management.ManagementFactory@getThreadMXBean().getThreadCount()'

十、profiler:火焰图

bash
# 启动采样
profiler start -e cpu

# 30 秒后停止,生成火焰图
profiler stop --format html

火焰图横轴是 CPU 时间占比,纵轴是调用栈。一眼看出哪个方法占用了最多 CPU。

十一、dashboard 与日志

bash
# 查日志(Arthas 内置 logger)
logger
logger --name ROOT --level debug

# 查运行参数
sysprop
sysenv

十二、热更新代码(高级)

风险高,生产慎用!仅用于紧急 bug 修复。

bash
# ① 下载源码
jad --source-only com.taskflow.service.OrderServiceImpl > /tmp/OrderServiceImpl.java

# ② 编译修改后的类
mc /tmp/OrderServiceImpl.java -d /tmp/output

# ③ 加载新类(热更新)
retransform /tmp/output/com/taskflow/service/OrderServiceImpl.class

实际生产中一般用 Arthas 的 redefine 命令(更稳定)。

十三、JVM 调优基础

内存参数

bash
java -Xms2g -Xmx2g -Xmn1g -XX:MaxMetaspaceSize=512m -jar app.jar
参数说明
-Xms初始堆大小
-Xmx最大堆大小
-Xmn年轻代大小
-XX:MaxMetaspaceSize元空间上限

GC 日志

bash
java -Xlog:gc*:file=/var/log/gc.log:time,uptime,level,tags -jar app.jar
bash
# 实时 GC 监控
jstat -gc <pid> 1000         # 每秒打印 GC 情况

内存分析

bash
# 导出堆 dump
jmap -dump:format=b,file=heap.bin <pid>

# 用 MAT 分析
# 1. Histogram:查最大对象
# 2. Leak Suspects:自动检测内存泄漏
# 3. Dominator Tree:查引用链

十四、线上问题排查流程

十五、Arthas 最佳实践

bash
# ① 监控脚本(批处理)
# 把常用命令写到文件
echo "dashboard" > /tmp/arthas.cmd
echo "thread -n 3" >> /tmp/arthas.cmd
echo "monitor com.taskflow.* * -c 5" >> /tmp/arthas.cmd

# 执行
java -jar arthas-boot.jar -f /tmp/arthas.cmd

# ② 远程连接
java -jar arthas-boot.jar --target-ip <ip> --port <port>
# 然后用 telnet / Web Console 远程连接
场景推荐命令
看全局状态dashboard
查 CPU 高thread -n 5
查慢方法trace + 条件过滤
查异常watch + throwExp
查调用统计monitor
查类是否更新jad
内存问题dashboard + jmap 导堆

十六、生产安全

bash
# ① 只允许特定用户使用 Arthas
# 配置项:arthas.enableArthas=false 关闭
# 通过环境变量控制:ARTHAS_ENABLE=false

# ② Arthas Web Console 用 HTTPS
# 默认是 HTTP,生产应配置反向代理

# ③ 监控 Arthas 自身
# Arthas 会占用一点 CPU/内存,需要监控

十七、本章小结

要点关键
启动java -jar arthas-boot.jar
全局dashboard
线程thread -n 3thread -b
监控watch(参数/异常)、trace(调用链)、monitor(统计)
反编译jad
表达式ognl '@Class@method()'
热更新jad + mc + retransform(慎用)
JVMjmap(堆)、jstat(GC)、jstack(线程)
流程dashboard → thread → trace → watch

动手练习

练习 1:基础题

在本地启动一个 Spring Boot 应用,连接 Arthas。执行:

  1. dashboard 看全局
  2. thread -n 3 找最忙线程
  3. watch 一个自定义方法,打印入参和返回值

练习 2:进阶题

模拟一个慢方法:

java
public void slowMethod() {
    Thread.sleep(500);
    System.out.println("done");
}

trace 命令追踪到具体的耗时环节。

练习 3:思考题

线上一个接口突然变慢(从 50ms 变成 2s),如何用 Arthas 快速定位根因?写出完整的排查步骤。


下一章第 78 章:Docker 镜像构建

本站基于 VitePress 构建 · 由 Codebook 团队维护