Linux 服务器 CPU 飙高后,我通常这样排查


CPU 飙高不等于一定有恶意进程,也不等于负载高就一定缺算力。这里按 load average、top、vmstat、pidstat 的区别拆解排查思路,定位高占用进程与线程,再区分正常业务、程序失控、I/O 等待和网络异常,并给出止损、复查与长期限制资源的步骤,适合 Linux 服务器运维人员直接照着操作。

服务器 CPU 飙高时,我最怕两种操作:看到 load average 高就立刻加服务器,或不分情况直接 kill -9。前者多半没弄清原因,后者会打断正在处理的请求。

在太云接触到的云服务器、物理服务器工单里,CPU 异常很常见,原因却不相同。我按“确认指标 → 找进程和线程 → 判断业务还是异常 → 止损 → 留证据”排查,流程不炫技,胜在不容易误杀。

先确认是不是真忙

uptime 的 load average 统计运行队列和不可中断 I/O 任务,不等于 CPU 使用率。8 核机器 load 到 8 不必然异常,1 分钟、5 分钟、15 分钟的变化更能说明压力是否持续。

我会同时看 top 和 vmstat 1 5。%us、%sy、%si、%wa、%st 分别代表用户态、系统态、软中断、I/O 等待和虚拟化环境被窃取时间。计算重通常 %us 高,网络包量大则软中断突出,磁盘慢会拉高 %wa。云主机 %st 长期偏高,我会先查宿主机争用。

找到具体进程和线程

别只盯 top 的总占用,我经常同时跑:

  • ps -eo pid,ppid,user,%cpu,%mem,stat,etime,cmd --sort=-%cpu | head -20
  • pidstat -u 1 5

前者看排行、父子关系和状态,后者连续采样,能抓到短暂冲高后回落的进程。状态为 D 多与 I/O 阻塞有关,先查磁盘。某线程长期占满单核,有权限时再对照 /proc/1234/task/线程ID/stack;Java 可用 jstack 1234 看线程栈。

判断是谁在消耗

  • 正常业务:把 CPU 曲线和访问日志、定时任务、备份任务对上。流量上涨不该靠杀进程解决。
  • 程序失控:服务重启后立刻冲高,常见于死循环、无限重试或序列化开销。PHP-FPM worker 过多也会争抢资源,盲目调大 pm.max_children 只会更糟。
  • 网络异常:若 %si 高且连接数增长快,用 ss -s、ss -antp | head -30 看来源,再对照 WAF、Nginx 日志。先限速或封禁异常来源,别急着重启整套服务。
  • 计划任务或入侵痕迹:检查 systemctl list-timers --all、crontab -l、/etc/cron*,再看 journalctl -u sshd --since today、last 和 SSH 密钥。生产机上别乱跑来路不明的一键清理脚本。

止损和后续处理

需要重启时,我会先留日志,再优雅重启。比如执行 journalctl -u nginx -n 200 > /tmp/nginx-before-restart.log,确认服务名后运行 systemctl restart nginx。能正常退出时用 kill -TERM 1234,别把 kill -9 当默认按钮。临时降优先级可用 renice -n 10 -p 1234,但这只是缓冲。

根因明确后,再通过 systemd 长期约束。在 unit 文件的 [Service] 段设置 CPUQuota=200%,改完执行 systemctl daemon-reload;再用 Restart=on-failure 处理崩溃,并给日志做好轮转。数值不能照抄,要结合业务峰值和机器核数压测。

我还会把异常时间、指标、进程、线程、处置和复发条件记进值班表。换人接手时,这些记录比一条“万能命令”有用。


外贸跨境电商网速提升,采购以太云服务器搭配类型实现网络不卡顿-晚高峰不拥堵!

PHP 官方修复两个高危漏洞,AI 时代让攻防成本发生了什么变化

评 论
请登录后再评论