写点什么

线上问题定位神器:Arthas

  • 2025-07-31
    福建
  • 本文字数:2029 字

    阅读完需:约 7 分钟

前言

我经历过凌晨 3 点被报警叫醒的慌乱,也体会过定位难题的煎熬。

90%的线上问题都源于"三个不知道":不知道哪慢、不知道谁卡、不知道为何错

这篇文章跟大家一起聊聊如何用 Arthas 快速定位线上问题,希望对你会有所帮助。


一、为什么常规工具在线上束手无策?


线上环境的三大特殊性



传统工具困局

  • 日志失效:未打印关键参数,事后无法复现

  • 监控滞后:1 分钟颗粒度丢失瞬时异常

  • JProfiler 瘫痪:CPU 飙高时根本打不开


Arthas 的降维打击优势

# 1秒接入生产环境  curl -O https://arthas.aliyun.com/arthas-boot.jar  java -jar arthas-boot.jar # 自动识别Java进程  
复制代码


二、五大问题定位场景

场景 1:慢接口定位

现象:订单查询接口 99%请求 200ms,1%突增到 5 秒

传统方案

// 盲目加日志  log.info("查询开始:{}", System.currentTimeMillis()); // 污染日志且低效  
复制代码


Arthas 精准打击

# 1. 追踪方法内部调用路径  trace com.example.OrderService getOrderById '#cost>1000' -n 5  
复制代码


输出火焰图:



根因定位:风控服务偶发 TCP 连接超时

解决方案

# 调整连接超时时间  risk:    client:      connection-timeout: 500      read-timeout: 1000  
复制代码


场景 2:线程阻塞之谜

现象:支付回调接口凌晨卡死

传统方案

jstack > thread.log # 但阻塞已结束  
复制代码


Arthas 破局

# 1. 查看线程状态分布  thread -b # 显示阻塞线程  
# 2. 监控锁竞争情况 watch java.util.concurrent.locks.ReentrantLock getQueueLength
复制代码


输出诊断报告:



根因定位:Logback 同步写日志阻塞业务线程

解决方案

<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">    <queueSize>1024</queueSize>    <appender-ref ref="FILE"/>  </appender>  
复制代码


场景 3:内存泄漏精准捕获

现象:容器每天重启一次

传统方案

jmap -histo:live pid # 触发Full GC破坏现场  
复制代码


Arthas 神操作

# 1. 监控堆内存对象  dashboard -i 5000 # 5秒刷新一次  
# 2. 追踪对象创建路径 vmtool --action getInstances --className LoginDTO --limit 10
复制代码


发现异常:

[LoginDTO] instances: 245,680 (增长0.5%/min)  
复制代码


源码定位

// 错误代码:ThreadLocal未清理  public class UserHolder {      private static ThreadLocal<LoginDTO> cache = new ThreadLocal<>();      public static void set(LoginDTO dto) {          cache.set(dto); // 线程复用导致堆积      }  }  
复制代码


解决方案

try {      // 业务代码  } finally {      UserHolder.remove(); // 强制清理  }  
复制代码


场景 4:热修复代码拯救崩溃

现象:新上线分页查询 OOM,回滚需 1 小时

传统方案

  1. 审批流程

  2. 合并代码

  3. 编译打包

  4. 重新部署 → 业务损失惨重


Arthas 力挽狂澜

# 1. 反编译问题方法  jad com.example.UserService listUsers  
# 2. 修改本地文件 vi UserService.java # 修复内存泄漏代码
# 3. 热更新类 redefine -c 327a3b4 /tmp/UserService.class
复制代码


热更新原理:



场景 5:数据不一致玄学案

现象:订单状态显示已支付,但数据库未更新

Arthas 破案

# 1. 监控方法入参/返回值  watch com.service.OrderService updateStatus    "{params,returnObj}" -x 3  
# 2. 观察调用链路 stack com.service.OrderService updateStatus
复制代码


捕获异常调用链:

updateStatus(OrderStatus.PAID)  // 正确调用    |- 线程1:支付回调  updateStatus(OrderStatus.CREATED) // 异常调用    |- 线程2:订单查询补偿任务  
复制代码


根因定位:补偿任务错误覆盖状态

解决方案

// 增加状态机校验  if (currentStatus != CREATED) {      throw new IllegalStateException("状态禁止回退");  }  
复制代码

三、Arthas 底层原理揭秘

为什么能无侵入诊断?



关键技术突破

  1. Attach 机制:通过VirtualMachine.attach注入 Agent

  2. 字节码织入:利用 ASM 修改方法体添加监控逻辑

  3. 类隔离:自定义 ClassLoader 防止污染业务代码

诊断命令执行流程



四、Arthas 高级组合技能

性能分析黄金组合:

# 1. 宏观概览  dashboard -i 5000  
# 2. 定位CPU热点 profiler start # 开始采样 profiler stop --format html # 生成火焰图
# 3. 追踪慢方法 trace *StringUtils substring '#cost>100'
复制代码


复杂问题排查框架:



五、避坑指南

必须遵守的三条军规

1、最小化原则

# 错误示范:监控所有方法  watch * *  
# 正确操作:精准定位 watch com.example.service.* *
复制代码


2、安全第一

# 禁止生产环境执行高危操作  reset * # 清除增强类  stop # 关闭Arthas  
复制代码


3、资源管控

# 限制内存占用  options save-result false  options batch-size 50  
复制代码

总结

Arthas 能力矩阵


架构师的三层境界

  1. 看现象:CPU 高→重启(新手)

  2. 看本质:线程阻塞→优化锁(进阶)

  3. 看未来:混沌工程主动注入故障(大师)

真正的高手不是解决问题,而是让问题无处遁形。

当你握紧 Arthas 这把手术刀,每一次线上危机都是展示技术深度的舞台。


文章转载自:苏三说技术

原文链接:https://www.cnblogs.com/12lisu/p/18991007

体验地址:http://www.jnpfsoft.com/?from=001YH

用户头像

还未添加个人签名 2025-04-01 加入

还未添加个人简介

评论

发布
暂无评论
线上问题定位神器:Arthas_Python_量贩潮汐·WholesaleTide_InfoQ写作社区