返回首页

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

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

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 -H → jstack 找栈 修复代码逻辑
多线程锁竞争 大量线程 Blocked jstack 搜 waiting for monitor 减小锁粒度、用并发容器
正则回溯 偶发 CPU 飙高 火焰图发现 Pattern 相关栈 避免嵌套量词、用原子组
频繁序列化 每次请求 new ObjectMapper 火焰图看 JSON 序列化热点 复用 ObjectMapper
JNI 调用 Java 进程 us 高但无 Java 栈 jstack 搜 JNI/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服务器五维排查
linux-mining-virus-investigation-guideLinux 服务器挖矿病毒完整的排查、清除与系统加固实战指南—附 kinsing 木马真实入侵案例与
linux-load-average-guideLinux Load Average 详解:概念、解读与实战判据 — 从 load average
server-suddenly-slow-troubleshooting-sop服务器突然卡顿完整排查 SOP,从告警到根因的 15 步取证流程
system-load-high-rsyslogd-case-study一个 rsyslogd 被 audit 审计日志刷屏导致的系统负载高案例,涵盖 CPU 拆解、软中断
jvm-container-oom-offheap-troubleshootingJVM OOM 排障