你好,我是风一样的树懒,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。
文章可能会比较长,主要解析的非常详解,或涉及一些底层知识,供面试高阶难度用。可以根据自己实际理解情况合理取舍阅读
graph TDA[问题现象] --> B{选择切入点}B -->|CPU高| C[线程/方法级分析]B -->|响应慢| D[调用链路追踪]B -->|内存泄漏| E[堆内存监控]C --> F[定位热点代码]D --> FE --> FF --> G[优化验证]
# 实时监控面板(每秒刷新)dashboard -i 1000 -n 5
关键指标:
THREAD:高CPU线程ID
MEM:堆内存/非堆内存占用
RUNNING:阻塞线程数
# 显示最忙线程Top3thread -n 3# 查看具体线程堆栈thread <线程ID>
典型案例:
"catalina-exec-1" Id=25 RUNNABLEat com.example.OrderService.calculateTax(OrderService.java:87) # 高CPU方法
# 监控方法执行耗时(5秒采样)profiler start --event cpu --duration 5profiler stop --format html > /tmp/cpu_profile.html
火焰图分析:
平顶山:单一方法高消耗
宽基座:基础方法高频调用
# 监控方法入参/返回值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
# 统计方法执行耗时(阈值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
# 跟踪Spring MVC接口全链路trace org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod '#cost>1000'
# 监控JDBC连接池watch org.apache.tomcat.jdbc.pool.ConnectionPool * '{params,returnObj,throwExp}' -x 3
# 生成HeapDump(需JDK8+)heapdump /tmp/heap.hprof# 对象直方图统计heap --live | grep com.example
# 查找泄漏对象vmtool --action getInstances --className com.example.CacheManager --express 'instances.length'# 追踪对象GC Rootoptions unsafe trueognl '@com.taobao.arthas.core.util.ObjectUtils@getGcRoot(instances[0])'
# 跟踪ReferenceQueuewatch java.lang.ref.ReferenceQueue poll 'returnObj != null' -x 3
# 热更新方法(需编译.class)redefine /tmp/UserService.class
# 监控锁竞争monitor -c 5 java.util.concurrent.locks.ReentrantLock getQueueLength
# 临时修改日志级别logger --name ROOT --level debug
## 问题现象- 现象: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执行时间监控
# ~/.arthasrcalias cpu_top=thread -n 3alias trace_slow=trace *Service '*' '#cost>500'
2.安全防护:
生产环境限制options unsafe使用
通过shutdown命令及时断开连接
# 诊断自动化脚本示例echo "thread -n 3" | java -jar arthas-client.jar 127.0.0.1 3658
通过系统化的Arthas诊断框架,可实现 5分钟定位常见问题,30分钟攻克复杂故障。
今天的内容就分享到这儿,喜欢的朋友可以关注,点赞。有什么不足的地方欢迎留言指出,您的关注是我前进的动力!