本文基于 Rocky Linux 9 实战环境,通过人为制造 CPU 高负载故障,完整演示从vmstat到top、ps、pstree、kill的 CPU 故障排查流程。
一、CPU 高负载排查思路
在 Linux 服务器中,如果监控系统发现:
CPU 使用率 > 90%不要第一时间执行:
kill -9正确的思路应该是:
CPU告警 ↓ 确认CPU是否真的繁忙 ↓ vmstat ↓ 判断CPU消耗类型 ↓ top ↓ 定位高CPU进程 ↓ ps ↓ 确认进程详细信息 ↓ pstree ↓ 分析进程父子关系 ↓ 判断异常原因 ↓ 正常停止 / kill / kill -9核心思想:
先定位,再处理。
二、使用 vmstat 判断 CPU 状态
执行:
vmstat 1 5含义:
1 → 每1秒采集一次 5 → 连续采集5次示例:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 5 0 0 365220 89784 1716832 0 0 1 23 4 1 1 1 98 0 0 4 0 0 365776 89784 1716816 0 0 0 76 7221 6896 22 78 0 0 0 4 0 0 365988 89784 1716816 0 0 0 4 7121 8171 22 78 0 0 0 4 0 0 365284 89784 1716840 0 0 0 100 7073 7678 22 79 0 0 0 6 0 0 367064 89784 1716848 0 0 0 84 7238 7834 23 77 0 0三、重点分析us、sy、id、wa、st
CPU 部分:
us sy id wa st分别表示:
| 参数 | 含义 |
|---|---|
us | 用户态 CPU |
sy | 内核态 CPU |
id | CPU 空闲时间 |
wa | I/O 等待 |
st | 被虚拟机偷走的 CPU 时间 |
1.us高
例如:
us sy id wa st 95 2 3 0 0说明:
CPU 主要消耗在用户态程序。
重点检查:
Java MySQL Python Nginx Shell 其他业务程序下一步:
top2.sy高
例如:
us sy id wa st 22 78 0 0 0说明大量 CPU 时间消耗在:
Linux内核 系统调用 网络 中断 进程调度 驱动这种情况需要进一步分析。
注意:
sy高并不一定代表 Linux 内核本身有问题,也可能是某个用户程序进行了大量系统调用。
这次实验中的yes就属于这种情况。
3.wa高
例如:
us sy id wa st 10 5 5 80 0说明大量时间用于等待 I/O。
重点检查:
iostat -xz 1 5以及:
iotop重点关注磁盘性能和 I/O 请求。
4.st高
例如:
us sy id wa st 20 5 5 0 70说明虚拟机的 CPU 资源可能被宿主机抢占。
云服务器、VMware 虚拟机环境中尤其需要关注。
四、使用 top 定位高 CPU 进程
执行:
top进入top后按:
P按照 CPU 使用率排序。
本次实验得到:
PID USER %CPU %MEM COMMAND 2583901 root 97.0 0.1 yes 2583899 root 96.0 0.1 yes 2583900 root 95.3 0.1 yes 2583902 root 95.3 0.1 yes 46699 root 2.0 2.4 YDService 2542416 root 2.0 7.4 kube-apiserver 2542452 root 1.0 1.9 etcd 2542831 root 1.0 2.9 kubelet此时非常明显:
yes yes yes yes占用了绝大部分 CPU。
五、为什么四个 yes 能达到接近 400%?
本服务器为:
4 CPU而每个:
yes ≈ 100%所以:
97 + 96 + 95.3 + 95.3 ≈ 383%意味着:
4 个 CPU 核心基本全部处于工作状态。
Linuxtop中,一个 CPU 核心可以达到约100%。
所以:
单核 → 100% 双核 → 200% 四核 → 400%这也是为什么多核服务器上看到:
%CPU = 300%并不代表服务器“超出了100%”。
六、使用 ps 进一步确认进程
找到 PID 后,不要急着杀。
例如:
ps -p 2583900 -o pid,ppid,user,%cpu,%mem,etime,cmd参数解释:
-p PID → 查询指定PID -o → 自定义输出字段 pid → 进程ID ppid → 父进程ID user → 运行用户 %cpu → CPU使用率 %mem → 内存使用率 etime → 进程运行时间 cmd → 启动命令例如:
PID PPID USER %CPU %MEM ETIME CMD 2583900 1 root 95.3 0.1 01:16:25 yes此时我们知道:
PID = 2583900 进程 = yes CPU = 95.3% PPID = 1七、理解 PID 和 PPID
Linux 中每个进程都有自己的 PID。
例如:
PID 2583900代表这个进程自己的编号。
而:
PPID代表:
Parent Process ID,父进程 ID。
例如:
bash ↓ yes那么:
bash → 父进程 yes → 子进程假设:
bash PID = 1000 yes PID = 2000那么:
PID 2000 PPID 1000八、为什么 yes 的 PPID 是 1?
本次实验中:
ps -p 2583900 -o cmd,pid,ppid得到:
CMD PID PPID yes 2583900 1再查看 PID 1:
ps -p 1 -o cmd,pid,ppid得到:
CMD PID PPID /usr/lib/systemd/systemd sh 1 0说明:
PID 0 ↓ PID 1 systemdLinux 的 PID 1 是非常重要的系统进程。
如果一个进程原来的父进程退出,子进程可能会被重新托管,由 PID 1 等进程接管。
因此:
yes ↓ PPID = 1并不意味着 systemd 一定直接启动了这个 yes。
九、使用 pstree 查看进程关系
执行:
pstree -p可以看到进程树。
如果只想查看某个进程:
pstree -p 2583900pstree的作用就是:
以树状结构显示 Linux 进程之间的父子关系。
这在排查:
异常进程 服务启动关系 僵尸进程 孤儿进程 脚本启动的进程时非常有用。
十、kill 的正确使用方法
找到异常进程以后,才进入处理阶段。
最基本:
kill PID例如:
kill 2583900默认发送:
SIGTERM也就是信号:
15它的含义是:
请求进程正常退出。
十一、kill -9 是什么?
kill -9 2583900其中:
9 = SIGKILL它会强制终止进程。
常见处理顺序:
kill PID ↓ 等待进程正常退出 ↓ 如果仍然存在 ↓ kill -9 PID所以不要形成:
发现CPU高 ↓ kill -9这样的习惯。
十二、一次杀多个 PID
本次实验中有四个yes:
2583899 2583900 2583901 2583902可以:
kill 2583899 2583900 2583901 2583902如果无法正常退出,再:
kill -9 2583899 2583900 2583901 2583902十三、按照进程名杀进程
如果确定需要按照进程名称处理,可以使用:
pkill yes强制:
pkill -9 yes也可以使用:
killall yes但是生产环境需要特别注意:
按照名称杀进程可能误杀同名进程。
因此生产环境更推荐:
确认进程 ↓ 确认PID ↓ 确认业务 ↓ 针对PID处理十四、为什么不能随便杀父进程?
例如:
父进程 ├── 子进程A ├── 子进程B └── 子进程C如果直接:
kill 父进程PID并不意味着:
子进程A 子进程B 子进程C一定全部退出。
父进程结束以后,子进程可能继续运行,并被其他进程重新托管。
所以:
杀父进程 ≠ 自动杀死所有子进程。
如果是 systemd 管理的服务,通常应该优先:
systemctl stop 服务名而不是直接杀某个进程。
十五、完整 CPU 排障案例
本次实验最终形成了完整的排障过程:
① 发现 CPU 异常 ↓ ② vmstat 1 5 ↓ ③ 发现 id=0 ↓ ④ 分析 us/sy/wa/st ↓ ⑤ top ↓ ⑥ 按 P 排序 ↓ ⑦ 发现 4 个 yes ↓ ⑧ 获取 PID ↓ ⑨ ps 查看 PPID、CPU、运行时间 ↓ ⑩ pstree 分析进程关系 ↓ ⑪ 确认是测试产生的异常进程 ↓ ⑫ kill PID ↓ ⑬ CPU恢复正常十六、生产环境中的进阶判断
真正工作时,不要只停留在:
top而应该根据vmstat的结果选择不同路线。
情况一:用户态 CPU 高
us 高重点:
top ps继续定位:
Java Python MySQL Nginx 业务程序情况二:内核态 CPU 高
sy 高继续调查:
mpstat -P ALL 1 5以及:
cat /proc/interrupts重点考虑:
系统调用 中断 网络 驱动 线程调度 内核活动情况三:I/O 等待高
wa 高执行:
iostat -xz 1 5继续分析:
磁盘利用率 IOPS await 队列 读写压力情况四:steal 高
st 高重点检查:
虚拟机 云服务器 宿主机资源竞争