线上Java服务BUG排查需要系统化思维+工具链配合,以下是经过实战验证的排查框架:
一、快速响应三板斧
-
日志定位
- 优先查看错误日志(ERROR级别)和警告日志(WARN级别)
- 使用
grep -C 10 "ERROR" app.log
查看上下文 - 关注高频出现的异常堆栈(如NullPointerException)
-
实时监控
bash复制代码
# 快速查看JVM状态
jstat -gcutil <pid> 1000 # 每秒输出GC情况
jmap -heap <pid> # 查看堆内存分布
jstack <pid> > thread_dump.log # 生成线程转储
-
服务状态检查
- 确认进程存活:
ps aux | grep java
- 检查端口监听:
netstat -tulnp | grep <port>
- 查看系统资源:
top -H -p <pid>
(查看线程级CPU)
- 确认进程存活:
二、深度诊断工具箱
- 性能分析
- Arthas(阿里开源诊断工具):
bash复制代码
watch DemoService '{params,returnObj}' -x 3 # 监控方法执行
heapdump /tmp/dump.hprof # 生成堆转储
thread -n 5 # 查看最忙线程
- async-profiler:火焰图分析CPU/内存热点
- Arthas(阿里开源诊断工具):
- 内存泄漏排查
- 使用MAT工具分析hprof文件:
- 检查Dominator Tree找大对象
- 查看GC Roots路径
- 分析线程局部变量(TLAB)
- 使用MAT工具分析hprof文件:
- 死锁检测
bash复制代码
jstack <pid> | grep -i "deadlock"
# 或使用Arthas的thread命令自动检测
三、典型场景排查路径
场景1:服务突然不可用
- 检查日志是否有OOM错误
- 查看
dmesg
确认是否触发OOM Killer - 分析堆转储文件寻找内存泄漏点
- 检查Full GC频率(
jstat -gcutil
)
场景2:接口响应变慢
- 使用Arthas监控方法耗时
- 检查线程池队列堆积情况
- 分析NIO线程是否存在阻塞(
jstack
找RUNNABLE线程) - 查看数据库连接池状态(
druid
监控页面)
场景3:偶发超时异常
- 检查GC日志(
grep "Full GC" gc.log
) - 分析网络抓包(
tcpdump -i any port 8080 -w capture.pcap
) - 查看操作系统文件句柄限制(
ulimit -n
)
四、防御性编程建议
- 关键路径添加埋点监控(如方法执行时间、队列大小)
- 配置JVM自动转储:
bash复制代码
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/oom_dump.hprof
- 使用Sentinel/Resilience4j实现熔断降级
- 生产环境启用Flight Recorder(JFR)持续记录
排查原则:先恢复服务,再分析根因。对于线上系统,优先通过日志和监控定位问题范围,避免直接进行Full GC或重启操作。复杂问题建议结合链路追踪系统(如SkyWalking)进行全链路分析。