ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

CPU 100% 高负载进阶排查与定位

CPU 100% 高负载进阶排查与定位 本文基于 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、stCPU 部分us sy id wa st分别表示参数含义us用户态 CPUsy内核态 CPUidCPU 空闲时间waI/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 和 PPIDLinux 中每个进程都有自己的 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 1ps -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本次实验中有四个yes2583899 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 ↓ ③ 发现 id0 ↓ ④ 分析 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 高重点检查虚拟机 云服务器 宿主机资源竞争
返回列表