r值高但top无高CPU进程,本质是vmstat与top观测粒度差异所致:vmstat的r统计就绪+运行态进程总数,而top刷新周期长、排序机制导致无法捕获短时高频进程;需用vmstat 0.5和pidstat -u 1定位调度风暴,结合D状态进程、I/O等待链、cgroup限频及中断压力综合排查。
热点进程的等待链分析">
看 r 值高但 top 无高 CPU 进程,先别怀疑工具
这根本不是 vmstat 或 top 出错,而是它们观测粒度和视角不同导致的“现象错位”:vmstat 的 r 统计的是**就绪态 + 运行态进程总数**(即排队等 CPU 的全部活进程),而 top 默认按 %CPU 排序、刷新周期 3 秒,根本抓不住只跑几毫秒就退出或阻塞的进程。所以你看到的不是“没负载”,是“负载太碎、太短、太隐”。
用 vmstat 0.5 和 pidstat -u 1 抓真实调度脉冲
把采样节奏压下去,才能看见肉眼不可见的调度风暴:
-
vmstat 0.5 20:每 500ms 采一次,连续 20 次,观察r是否持续 ≥ 核数(比如 8 核服务器上r长期在 10–15 波动) -
pidstat -u 1 10:每秒输出每个进程的 CPU 使用率,重点关注%CPU瞬时峰值(哪怕只有 2%–5%)和minflt(次缺页)是否突增——这是高频 fork 或内存抖动的典型信号 - 如果发现某进程
%CPU平均不到 1%,但minflt/s高达几百甚至上千,基本可锁定为轻量子进程洪流(如日志轮转脚本、健康检查探针、CGI 类服务)
排查 D 状态进程与 I/O 等待链
r 高但 us+sy 低、wa 明显(>20%),大概率不是 CPU 不够,而是进程卡在 I/O 路径上,反复进入就绪队列又立刻被挂起:
- 运行
ps aux | awk '$8 ~ /D/ {print}'查 D 状态进程(不可中断睡眠),这类进程 kill -9 无效,却持续占r位 - 立刻执行
iostat -x 2,盯住await(平均等待毫秒)和avgqu-sz(平均队列深度):SSD 上await > 1ms且avgqu-sz > 2就已异常;NFS 挂载点更要警惕超时重试引发的队列雪崩 - 注意
b列(uninterruptible sleep 进程数):若b与r同步高位,说明 I/O 或内核锁争用是根因,不是 CPU 调度问题
别漏掉 cgroup throttling 和中断隐形开销
容器环境或资源受限系统里,r 高可能根本不是进程真想跑,而是被硬限频后反复“排队→被掐→再排队”:
- 查 cgroup 限制:
cat /sys/fs/cgroup/cpu/$(ps -o cgroup= -p $(pgrep -f "服务名")) | grep cpu.max,若看到类似10000 100000(即 10% CPU quota),就是 throttling 在作祟 - 看中断压力:
vmstat 1 5中的in(每秒中断数)若 >5000 且与r正相关,要检查网卡软中断、定时器、NVMe 驱动等是否过载;cat /proc/interrupts可定位热点中断源 - 内核线程(如
kswapd、khugepaged)不显示在top默认视图,但会推高sy和cs,用top -H或htop -t才能看见它们的上下文切换痕迹
真正难的从来不是看到 r 高,而是判断它背后是 fork 风暴、D 状态堆积、cgroup 限频,还是中断洪水——这些线索散落在不同命令的输出里,必须交叉比对,不能只盯一个数字。









