web学习笔记编程技术学习与分享

一次线上 CPU 飙高的排查过程

2026 年 07 月 06 日约 3 分钟阅读 运维与部署

记录一次典型的 CPU 飙高排查。过程比结论更有价值——命令都会用,但顺序和取舍才是经验。

背景

下午三点告警:CPU 使用率 92%,持续 5 分钟。业务响应变慢但未完全不可用。

第一步:谁在吃 CPU

top -c                          # 按 P 排序,看进程与完整命令行

前几名全是 php-fpm worker。说明是业务代码在烧 CPU,不是系统任务。如果这里是 mysqld,路径就完全不同(转去查慢查询)。

第二步:在干什么

pidstat -u -p <pid> 1 5         # 确认持续吃满
strace -p <pid> -c -f           # 汇总系统调用 10 秒

strace 显示大量 read(),来自同一个文件——一个每请求都会加载的大配置文件被反复解析。配合 FPM 慢日志(request_slowlog_timeout=2)抓到的栈,指向刚上线的一个改动:把一个 3MB 的 JSON 规则文件改成了每次请求重新解析。

第三步:确认影响面

# FPM 状态页
curl -s localhost/fpm-status
# active = max_children,listen queue 在涨 —— worker 被慢请求占满

请求变慢的本质:每个请求都变重,worker 周转率下降,排队开始。

第四步:止血

两条路:回滚该次发布;或热修复(把解析结果做进程内缓存)。当时选择回滚——变更记录完整、回滚脚本现成,5 分钟完成。CPU 回落到 18%。

第五步:修复与复盘

修复方案是「文件 mtime 未变时复用 opcache 缓存的解析结果」,并用 ab 压测对比:修复后 QPS 提升 2.4 倍。复盘产出两条规则:

  1. 涉及文件 IO 或外部调用的改动,必须提供压测数据;
  2. FPM 的 request_slowlog_timeout 从 5 秒收紧到 2 秒——这次如果不是 strace 抓巧,定位还会更久。

复用这个模板

任何 CPU 飙高的排查都可以走这个顺序:

  1. top 定位进程(业务进程还是系统进程);
  2. strace/pidstat/perf 看它具体在干什么;
  3. 查该组件的「慢日志/状态页」确认影响面;
  4. 止血优先于根因(回滚、扩容、降级);
  5. 修复后必须复盘,把个案变成规则。

最后一条提醒:没有变更就没有故障。排查第一句永远是「最近改了什么」——这次答案是提前准备好的,因为发布记录完整。

故障排查性能Linux