CPU过高:Arthas实时诊断怎样做分析

你好,我是风一样的树懒,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。

点击下方👇关注公众号,带你一起复习后端技术,看看面试考点,补充积累技术知识,每天都为面试准备积累

文章可能会比较长,主要解析的非常详解,或涉及一些底层知识,供面试高阶难度用。可以根据自己实际理解情况合理取舍阅读


1
核心诊断流程设计(5步法)


graph TD    A[问题现象] --> B{选择切入点}    B -->|CPU高| C[线程/方法级分析]    B -->|响应慢| D[调用链路追踪]    B -->|内存泄漏| E[堆内存监控]    C --> F[定位热点代码]    D --> F    E --> F    F --> G[优化验证]


02
CPU高场景分析(4大武器)


1. 全局资源定位

# 实时监控面板(每秒刷新)dashboard -i 1000 -n 5

关键指标:

  • THREAD:高CPU线程ID  

  • MEM:堆内存/非堆内存占用  

  • RUNNING:阻塞线程数  


2. 线程级定位

# 显示最忙线程Top3thread -n 3# 查看具体线程堆栈thread <线程ID>

典型案例:

"catalina-exec-1" Id=25 RUNNABLE    at com.example.OrderService.calculateTax(OrderService.java:87# 高CPU方法


3. 方法级采样

# 监控方法执行耗时(5秒采样)profiler start --event cpu --duration 5profiler stop --format html > /tmp/cpu_profile.html

火焰图分析:

  • 平顶山:单一方法高消耗  

  • 宽基座:基础方法高频调用  


4. 动态代码插桩

# 监控方法入参/返回值watch com.example.OrderService calculateTax '{params, returnObj}' -n 5 -x 3

输出示例:

method=com.example.OrderService.calculateTax location=AtExitparams[0]=Order[id=123,amount=1000.0]returnObj=150.0


03
响应慢问题排查(全链路追踪)


1. 慢方法识别

# 统计方法执行耗时(阈值500ms)trace com.example.*Service * '#cost>500' -n 5

输出解读:

`---ts=2023-08-20 15:32:45;thread_name=catalina-exec-3;id=2e;is_daemon=true;priority=5;TCCL=org.springframework.boot.loader.LaunchedURLClassLoader@4b85612c    `---[521.743075ms] com.example.UserService:getUserDetail()        +---[0.12% 0.65ms] com.example.dao.UserDAO:selectById() #1        +---[98.73% 515.2ms] java.net.SocketInputStream:socketRead0() #2 <--- 网络阻塞        `---[1.15% 6.0ms] com.example.util:formatUser() #3

2. 调用链路追踪

# 跟踪Spring MVC接口全链路trace org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod '#cost>1000'

3. 数据库慢查询定位

# 监控JDBC连接池watch org.apache.tomcat.jdbc.pool.ConnectionPool * '{params,returnObj,throwExp}' -x 3


04
内存泄漏排查(3层分析法)


1. 堆内存快照

# 生成HeapDump(需JDK8+)heapdump /tmp/heap.hprof# 对象直方图统计heap --live | grep com.example

2. 对象引用链追踪

# 查找泄漏对象vmtool --action getInstances --className com.example.CacheManager --express 'instances.length'# 追踪对象GC Rootoptions unsafe trueognl '@com.taobao.arthas.core.util.ObjectUtils@getGcRoot(instances[0])'

3. 软引用/弱引用监控

# 跟踪ReferenceQueuewatch java.lang.ref.ReferenceQueue poll 'returnObj != null' -x 3


05
进阶场景解决方案


1. 动态修复代码

# 热更新方法(需编译.class)redefine /tmp/UserService.class

2. 并发竞争检测

# 监控锁竞争monitor -c 5 java.util.concurrent.locks.ReentrantLock getQueueLength

3. 日志动态调参
# 临时修改日志级别logger --name ROOT --level debug


06
诊断报告模板


问题分析报告

## 问题现象- 现象:API响应时间从50ms突增至2s- 时段:2023-08-20 14:00 ~ 15:00## Arthas诊断过程1. `dashboard`发现线程池满2. `thread -n 3`定位到DB连接线程阻塞3. `trace`追踪到MyBatis批量插入操作4. `watch`监控到SQL参数包含10万条记录## 根因分析- 批量插入未分页导致数据库锁表## 优化方案- 增加批量操作分页限制(每批500条)- 添加SQL执行时间监控

07
最佳实践建议


1.诊断前置化:将常用命令封装为alias
# ~/.arthasrcalias cpu_top=thread -n 3alias trace_slow=trace *Service '*' '#cost>500'


2.安全防护:

  • 生产环境限制options unsafe使用  

  • 通过shutdown命令及时断开连接

      

3.自动化集成:
# 诊断自动化脚本示例echo "thread -n 3" | java -jar arthas-client.jar 127.0.0.1 3658

通过系统化的Arthas诊断框架,可实现 5分钟定位常见问题,30分钟攻克复杂故障。

今天的内容就分享到这儿,喜欢的朋友可以关注,点赞。有什么不足的地方欢迎留言指出,您的关注是我前进的动力!

END


扫码关注

一起积累后端知识
不积跬步,无以至千里
不积小流,无以成江海

喜欢此内容的人还喜欢

《Java面试题指南》回归啦~


一个阿里二面面试官必问的问题


Lambda表达式说爱你不容易


分享面试:mysql数据库索引失效的情况


Spring-Boot中一个不起眼的好工具StopWatch