系统负载高但CPU使用率低,说明大量进程处于R或D状态等待资源而非运行,主因是磁盘I/O阻塞、NFS响应慢、内核锁争用或硬件故障;需用uptime、ps、iostat、vmstat和dmesg交叉验证定位。

系统负载高但 CPU 使用率低,说明有大量进程没在跑 CPU,而是在等别的资源——最常见的是磁盘 I/O、内核锁、NFS 响应或硬件故障。关键不是看 CPU 有没有空,而是看进程卡在哪。
先看负载和 CPU 状态是否真矛盾
运行 uptime 或 top,确认 load average 数值(比如 12.5)和当前 CPU idle(比如 95%)确实反差大。再用 nproc 查清逻辑 CPU 核心数。如果 8 核机器 load 长期 > 8,就说明有进程排队或卡住,不是误报。
- top 中按 1 键看各核使用是否均衡,排除单核打满但整体 idle 高的情况
- 留意 %Cpu(s) 行里的 wa(I/O wait)值:持续 > 5% 就是强信号
- 观察 st(steal time):云服务器上若 > 5%,说明宿主机抢了你的 CPU 时间
重点查 D 状态进程和 I/O 等待
D 状态(不可中断睡眠)进程不占 CPU,但算进负载。它们通常卡在磁盘写、NFS 请求、RAID 同步或驱动层,是“高负载低 CPU”的头号嫌疑。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 执行 ps -eo stat,pid,comm | grep "^D",列出所有 D 状态进程
- 对每个 D 进程,用 cat /proc/[PID]/stack 看内核调用栈,确认卡在
ext4_writepages、nfs_wait_on_request还是jbd2_log_wait_commit - 用 iostat -x 1 3 查磁盘:重点关注 %util(接近 100% 表示设备饱和)和 await(> 10ms 提示延迟异常)
交叉验证瓶颈类型
单一命令容易漏掉线索,组合使用才能定位真实瓶颈。
- vmstat 1 5:盯 r(运行队列长度)、b(阻塞进程数)、cs(上下文切换)。若 b 高 + r 高 + wa 高,基本锁定 I/O
- pidstat -d 1:看哪个进程读写最多(kB_rd/s、kB_wr/s),尤其注意短命进程反复刷盘
-
dmesg -T | grep -i "error\|timeout\|ata":找磁盘硬件报错,如
I/O error, dev sda或end_request: I/O error
别忽略其他隐藏原因
除了磁盘 I/O,这几类问题也常导致负载虚高:
- 高频 fork:日志轮转、监控脚本每秒启停,vmstat 中 cs 值飙升(>10 万/秒),但 top 抓不到具体进程
-
内核线程卡死:如
kswapd0(内存回收)、kworker(内核任务)长时间 D 住,常伴随内存紧张或驱动 bug - NFS 或 CIFS 挂载异常:客户端卡在远程文件系统响应上,df -h 可能卡住,strace df 能看到阻塞点
- 锁竞争:数据库死锁、容器共享存储争用,进程状态可能是 R(排队)或 D(内核锁),需结合应用日志分析

















