找回密码
 立即注册
首页 业界区 业界 线上问题定位神器:Arthas

线上问题定位神器:Arthas

撷监芝 6 小时前
前言

我经历过凌晨3点被报警叫醒的慌乱,也体会过定位难题的煎熬。
90%的线上问题都源于"三个不知道":不知道哪慢、不知道谁卡、不知道为何错
这篇文章跟大家一起聊聊如何用Arthas快速定位线上问题,希望对你会有所帮助。
一、为什么常规工具在线上束手无策?

线上环境的三大特殊性
1.png

传统工具困局

  • 日志失效:未打印关键参数,事后无法复现
  • 监控滞后:1分钟颗粒度丢失瞬时异常
  • JProfiler瘫痪:CPU飙高时根本打不开
Arthas的降维打击优势
  1. # 1秒接入生产环境  
  2. curl -O https://arthas.aliyun.com/arthas-boot.jar  
  3. java -jar arthas-boot.jar # 自动识别Java进程  
复制代码
二、五大问题定位场景

场景1:慢接口定位

现象:订单查询接口99%请求200ms,1%突增到5秒
传统方案
  1. // 盲目加日志  
  2. log.info("查询开始:{}", System.currentTimeMillis()); // 污染日志且低效  
复制代码
Arthas精准打击
  1. # 1. 追踪方法内部调用路径  
  2. trace com.example.OrderService getOrderById '#cost>1000' -n 5  
复制代码
输出火焰图:
2.png

根因定位:风控服务偶发TCP连接超时
解决方案
  1. # 调整连接超时时间  
  2. risk:  
  3.   client:  
  4.     connection-timeout: 500  
  5.     read-timeout: 1000  
复制代码
场景2:线程阻塞之谜

现象:支付回调接口凌晨卡死
传统方案
  1. jstack > thread.log # 但阻塞已结束  
复制代码
Arthas破局
  1. # 1. 查看线程状态分布  
  2. thread -b # 显示阻塞线程  
  3. # 2. 监控锁竞争情况  
  4. watch java.util.concurrent.locks.ReentrantLock getQueueLength  
复制代码
输出诊断报告:
3.png

根因定位:Logback同步写日志阻塞业务线程
解决方案
  1.   
  2.   <queueSize>1024</queueSize>  
  3.    
  4. </appender>  
复制代码
场景3:内存泄漏精准捕获

现象:容器每天重启一次
传统方案
  1. jmap -histo:live pid # 触发Full GC破坏现场  
复制代码
Arthas神操作
  1. # 1. 监控堆内存对象  
  2. dashboard -i 5000 # 5秒刷新一次  
  3. # 2. 追踪对象创建路径  
  4. vmtool --action getInstances --className LoginDTO --limit 10  
复制代码
发现异常:
  1. [LoginDTO] instances: 245,680 (增长0.5%/min)  
复制代码
源码定位
  1. // 错误代码:ThreadLocal未清理  
  2. public class UserHolder {  
  3.     private static ThreadLocal<LoginDTO> cache = new ThreadLocal<>();  
  4.     public static void set(LoginDTO dto) {  
  5.         cache.set(dto); // 线程复用导致堆积  
  6.     }  
  7. }  
复制代码
解决方案
  1. try {  
  2.     // 业务代码  
  3. } finally {  
  4.     UserHolder.remove(); // 强制清理  
  5. }  
复制代码
场景4:热修复代码拯救崩溃

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

  • 审批流程
  • 合并代码
  • 编译打包
  • 重新部署 → 业务损失惨重
Arthas力挽狂澜
  1. # 1. 反编译问题方法  
  2. jad com.example.UserService listUsers  
  3. # 2. 修改本地文件  
  4. vi UserService.java # 修复内存泄漏代码  
  5. # 3. 热更新类  
  6. redefine -c 327a3b4 /tmp/UserService.class  
复制代码
热更新原理:
4.png

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

现象:订单状态显示已支付,但数据库未更新
Arthas破案
  1. # 1. 监控方法入参/返回值  
  2. watch com.service.OrderService updateStatus  
  3.   "{params,returnObj}" -x 3  
  4. # 2. 观察调用链路  
  5. stack com.service.OrderService updateStatus  
复制代码
捕获异常调用链:
  1. updateStatus(OrderStatus.PAID)  // 正确调用  
  2.   |- 线程1:支付回调  
  3. updateStatus(OrderStatus.CREATED) // 异常调用  
  4.   |- 线程2:订单查询补偿任务  
复制代码
根因定位:补偿任务错误覆盖状态
解决方案
  1. // 增加状态机校验  
  2. if (currentStatus != CREATED) {  
  3.     throw new IllegalStateException("状态禁止回退");  
  4. }  
复制代码
三、Arthas底层原理揭秘

为什么能无侵入诊断?
5.png

关键技术突破

  • Attach机制:通过VirtualMachine.attach注入Agent
  • 字节码织入:利用ASM修改方法体添加监控逻辑
  • 类隔离:自定义ClassLoader防止污染业务代码
诊断命令执行流程
6.png

四、Arthas高级组合技能

性能分析黄金组合:
  1. # 1. 宏观概览  
  2. dashboard -i 5000  
  3. # 2. 定位CPU热点  
  4. profiler start # 开始采样  
  5. profiler stop --format html # 生成火焰图  
  6. # 3. 追踪慢方法  
  7. trace *StringUtils substring '#cost>100'  
复制代码
复杂问题排查框架:

7.png

五、避坑指南

必须遵守的三条军规

  • 最小化原则
  1. # 错误示范:监控所有方法  
  2. watch * *  
  3. # 正确操作:精准定位  
  4. watch com.example.service.* *  
复制代码

  • 安全第一
  1. # 禁止生产环境执行高危操作  
  2. reset * # 清除增强类  
  3. stop # 关闭Arthas  
复制代码

  • 资源管控
  1. # 限制内存占用  
  2. options save-result false  
  3. options batch-size 50  
复制代码
总结

Arthas能力矩阵
问题类型核心命令效果方法级追踪trace/watch精确到毫秒的性能分析线程诊断thread/thread -b秒级定位阻塞源内存分析heapdump/vmtool不触发GC的内存快照动态修复jad/redefine免重启热更新架构师的三层境界

  • 看现象:CPU高→重启(新手)
  • 看本质:线程阻塞→优化锁(进阶)
  • 看未来:混沌工程主动注入故障(大师)
真正的高手不是解决问题,而是让问题无处遁形。
当你握紧Arthas这把手术刀,每一次线上危机都是展示技术深度的舞台。
最后说一句(求关注,别白嫖我)

如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下我的同名公众号:苏三说技术,您的支持是我坚持写作最大的动力。
求一键三连:点赞、转发、在看。
关注公众号:【苏三说技术】,在公众号中回复:进大厂,可以免费获取我最近整理的10万字的面试宝典,好多小伙伴靠这个宝典拿到了多家大厂的offer。
本文收录于我的技术网站:http://www.susan.net.cn

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册