返回首页

CPU 100% 故障排查实战:从告警到根因的全链路分析与 10 大场景

📅 创建于 2026-06-04 🔄 更新于 2026-06-04 📝 735 字

CPU 100% 故障排查实战:从告警到根因的全链路分析与 10 大场景

来源:马哥Linux运维 | 发布日期:2026-06-03

CPU 使用率组成

类别 含义 说明
us 用户态 CPU 应用自身计算逻辑
sy 内核态 CPU 系统调用、内存分配、I/O
wa 等待 I/O 磁盘/网络 I/O 瓶颈
hi/si 硬/软中断 网卡收包、存储中断风暴
id 空闲 100% 表示 CPU 完全空闲

多核机器上 top 显示 CPU% 按单核计算(8 核满跑 = 800%),判断是否跑满看 id 列是否为 0 以及 load average 是否远大于 CPU 核心数。

排查七步法

第一步:确认影响范围

单台还是集群?影响多少业务?什么时候开始的?

# K8s 集群
kubectl top nodes
kubectl get pods -o wide | grep -v Running

第二步:定位异常进程

top                  # Shift+P 按 CPU 排序
top -bn1 -p <PID>    # 单进程 CPU
# 可疑进程查启动路径和网络连接
ls -la /proc/<PID>/exec
ss -tunapl | grep <PID>

第三步:分析 CPU 来源

pidstat -p <PID> 1 5    # %usr vs %system
# us 高 → 应用计算;sy 高 → 大量系统调用

Java 进程优先看 GC:

jstat -gcutil <PID> 1000 10
# 关注: O(Old使用率) YGC/YGCT FGC/FGCT
# FGC 频繁 + GCT 高 → GC 是 CPU 主因

第四步:线程级定位

# top 线程模式 → hex 转换 → jstack 搜索
top -bn1 -H -p <PID>          # 找 CPU 最高的线程 PID
printf '%x\n' <decimalPID>    # 转十六进制
jstack <PID> > /tmp/jstack.log
grep -A 20 "nid=0x<hex>" /tmp/jstack.log
# 或直接用 arthas
thread -n 10                  # Top 10 CPU 线程

第五步:系统级分析

vmstat 1 5           # r(运行队列)/us/sy/wa
mpstat -P ALL 1 5    # 每核 CPU
iostat -x 1 5        # 磁盘 I/O
perf record -F 99 -p <PID> -g -- sleep 30 && perf report

第六步:定位根因

通过前五步应能判断根因属于哪类。见下方10大场景速查。

第七步:修复及验证

修复根因后验证:

watch -n 2 "top -bn1 | head -20"           # CPU 回落
watch -n 5 "jstat -gcutil <PID> \| tail -1" # GC 正常
curl -o /dev/null -s -w "RTT: %{time_total}s\n" http://localhost:8080/health

真实案例:MySQL 备份锁导致的级联故障

故障链路

MySQL 从库备份锁表 → 从库查询超时 → 线程池 200 个请求积压
→ Old 区持续上涨 → Full GC 每 30 秒/次(STW 5-8 秒)→ CPU 100%

排查过程

  1. top 看到 Java 进程 CPU 900%+(16核)
  2. jstat -gcutil → Old 区 99%,FGC 每 30 秒一次
  3. arthas 看线程 → 180 个线程处于 TIMED_WAITING(等数据库返回)
  4. 联系 DBA → 从库备份锁表导致复制延迟

修复

  • 临时(10 分钟): 关闭备份任务释放表锁,CPU 立即回落
  • 根本(3 天): 备份加 --single-transaction;JVM -Xmx 从 4g 提到 8g;添加从库延迟告警;超时熔断降级到主库

10 大 CPU 故障场景速查

场景 特征 排查工具 修复方向
GC 频繁 O 区持续上涨,FGC 次数多 jstat -gcutil 增大 -Xmx、调 GC 算法、修复内存泄漏
死循环/无限递归 单线程 CPU 固定占满 top -Hjstack 找栈 修复代码逻辑
多线程锁竞争 大量线程 Blocked jstackwaiting for monitor 减小锁粒度、用并发容器
正则回溯 偶发 CPU 飙高 火焰图发现 Pattern 相关栈 避免嵌套量词、用原子组
频繁序列化 每次请求 new ObjectMapper 火焰图看 JSON 序列化热点 复用 ObjectMapper
JNI 调用 Java 进程 us 高但无 Java 栈 jstackJNI/native 检查 native 库代码
网络 I/O 中断风暴 si(软中断)高 cat /proc/softirqs 多队列网卡、RPS 调优
加密解密 HTTPS/AES 密集型 perf stat -e 'crypto' 用 AES-NI 硬件加速、TLS 1.3
Python GIL Python 多线程 CPU 利用率低 ps -eLf \| grep <PID> 用多进程替代多线程
数据库慢查询 wa 高,大量数据库线程阻塞 SHOW FULL PROCESSLIST 优化查询、加索引、读写分离

其他语言进程排障

Python

pidstat -t -p <PID> 1 5
py-spy record -o /tmp/profile.svg --pid <PID>

Go

curl http://localhost:6060/debug/pprof/profile?seconds=30 > cpu.prof
go tool pprof cpu.prof    # 交互界面输入 top

JVM 配置参考(8 核 16G 机器)

java -Xms8g -Xmx8g \
  -XX:+UseG1GC \
  -XX:MaxGCPauseMillis=200 \
  -XX:+HeapDumpOnOutOfMemoryError \
  -XX:HeapDumpPath=/var/log/heapdump.hprof \
  -Xlog:gc*:file=/var/log/gc.log:time,uptime,level,tags:filecount=10,filesize=10M \
  -XX:MetaspaceSize=256m \
  -XX:MaxMetaspaceSize=512m \
  -jar your-app.jar

故障复盘检查清单

□ 故障发生/发现/恢复时间
□ 影响范围(哪些业务/用户)
□ 根因 + 触发条件 + 扩大因素
□ 临时修复 + 根本修复措施
□ 监控盲区(需补充的监控)
□ 流程改进 + 预防措施

风险提醒

操作 风险 建议
重启 Java 进程 丢失 JVM 状态(线程栈/GC/内存分布) 先分析再重启,保留现场
strace -f 进程变慢 10x+ -c 统计模式替代逐行跟踪
jmap -dump 触发 Full GC,消耗大量磁盘 I/O 低峰期操作,导出到独立磁盘
perf record 对性能影响较小 采样时间不宜过长

部署回滚

kubectl rollout history deployment/<name> -n <ns>
kubectl rollout undo deployment/<name> -n <ns>
kubectl rollout undo deployment/<name> -n <ns> --to-revision=<N>

关联页面

页面关联点
cpu-spike-troubleshooting-guideCPU 排查方法论
java-cpu-100-case-studyJava CPU 100% 排查实战
cpu-spike-3-commands三命令排查法
fullstack-performance-troubleshooting全栈性能排障
server-performance-four-dimensions服务器五维排查
jvm-container-oom-offheap-troubleshootingJVM OOM 排障