当线上 Java 应用出现 CPU 100% 告警时,往往意味着服务响应变慢、接口超时甚至节点宕机。本手册将为你梳理一套从“紧急定位”到“深度分析”再到“根治优化”的标准化排查流程。
阶段一:紧急定位与现场快照(黄金5分钟)
当监控告警提示 CPU 飙升时,首要任务是快速锁定“元凶”线程并保留现场。
1. 定位高耗 CPU 的进程与线程
- 查找进程:执行
top命令,按P键让进程按 CPU 降序排列,找到占用最高的 Java 进程 PID(例如12345)。 - 查找线程:执行
top -Hp <PID>(例如top -Hp 12345),查看该进程下所有线程的 CPU 占用情况,找到占用最高的线程 ID(TID,例如12346)。
2. 导出线程堆栈(Thread Dump)
线程堆栈是排查 CPU 问题的“黑匣子”,必须第一时间导出:
# 导出当前所有线程的堆栈信息
jstack <PID> > /tmp/thread_dump.log
小技巧:如果条件允许,建议每隔 5 秒执行一次,连续导出 3 次,以便对比分析线程状态的持续性。
阶段二:深度分析与根因锁定(抽丝剥茧)
拿到线程 ID 和堆栈日志后,需要将两者关联起来分析。
1. 转换线程 ID 为十六进制
JVM 堆栈中的线程 ID(nid)是以十六进制显示的,需要进行转换:
printf "%x\n" <TID> # 例如 printf "%x\n" 12346,输出结果为 303a
2. 关联堆栈定位代码行
在导出的 thread_dump.log 中搜索刚才转换的十六进制 ID:
grep "0x303a" -A 30 /tmp/thread_dump.log
查看搜索结果中线程的状态(java.lang.Thread.State)及堆栈顶部指向的代码行(例如 at com.example.Service.process(Service.java:88)),这通常就是导致 CPU 飙升的“案发现场”。
3. 结合 GC 情况排查(排除假性 CPU 高)
有时候 CPU 高并非业务代码导致,而是 JVM 在疯狂进行垃圾回收(GC)。执行以下命令观察 GC 频率:
jstat -gcutil <PID> 1000 10
如果 FGC(Full GC 次数)在短时间内疯狂增长,且 FGCT(Full GC 总耗时)占比极高,说明 CPU 飙升是由频繁 Full GC 引起的。此时应转为排查内存泄漏或堆内存配置过小的问题。
阶段三:常见根因与修复方案(对症下药)
根据堆栈信息和 GC 状态,通常可以归纳为以下几类核心根因:
| 根因分类 | 典型特征 | 修复与优化方案 |
|---|---|---|
| 死循环 / 无限递归 | 线程状态为 RUNNABLE,堆栈长期停留在某几行代码。 | 审查代码逻辑,确保循环有明确的退出条件;避免过深的递归调用。 |
| 频繁 Full GC | jstat 显示 FGC 极高,堆栈中大量出现 GC 相关线程。 | 排查内存泄漏(如静态集合无限增长),优化大对象创建,或合理调大 -Xmx 堆内存。 |
| 锁竞争 / 线程阻塞 | 大量线程状态为 BLOCKED,等待同一把锁。 | 减小锁的粒度(如使用 ConcurrentHashMap 替代全局锁),或使用无锁结构(CAS)。 |
| 低效算法与序列化 | 热点方法涉及复杂正则、大 JSON 序列化或嵌套循环。 | 优化正则表达式(避免灾难性回溯),使用高性能序列化框架(如 Protobuf/Kryo)。 |
阶段四:神器 Arthas 极速排查(强烈推荐)
如果生产环境允许使用阿里开源的 Arthas 诊断工具,可以极大提升排查效率,跳过繁琐的手动转换步骤。
1. 启动并关联进程
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar # 选择对应的 Java 进程序号
2. 一键定位高 CPU 线程
输入命令 thread -n 3,Arthas 会直接列出当前最繁忙的 3 个线程,并直接打印出对应的堆栈代码行,无需手动转换十六进制。
3. 生成 CPU 火焰图(可视化分析)
如果热点分散难以定位,可以使用 Arthas 的 profiler 功能:
profiler start # 开始采样,默认采样 30 秒
profiler stop # 停止采样并生成火焰图 HTML 文件
将生成的 HTML 文件下载到本地用浏览器打开,图中面积最大的红色色块就是最消耗 CPU 的方法。
阶段五:复盘与长效预防(亡羊补牢)
- 代码评审(Code Review)常态化:将“禁止无退出条件的循环”、“慎用复杂正则”、“大集合操作需分页”等纳入团队的 CR 必查项。
- 上线前压测:模拟高并发场景,观察 CPU、GC 的表现,提前发现性能瓶颈。
- 完善监控告警:除了基础的 CPU 告警,建议增加对 Full GC 频率、线程池活跃数、接口响应耗时的监控,做到防患于未然。
评论区