用 vmstat 1 看 r、cs、wa 三列:r>cpu核心数说明任务排队,cs>50000反映调度开销大,wa>20%表明i/o等待严重;首行无效,须从第二行读实时值。

怎么看 CPU 是否被拖垮:用 vmstat 1 抓住关键信号
别急着开 top 看哪个进程红了——虚拟机里真正拖慢响应的,往往是看不见的上下文切换和 I/O 等待。vmstat 一行就能暴露底层压力源。
运行 vmstat 1(每秒刷新),重点盯三列:r(就绪队列长度)、cs(每秒上下文切换)、wa(I/O 等待占比):
-
r > CPU核心数:说明有任务在排队等 CPU,不是“忙”,是“抢不到” -
cs > 50000:虚拟机常见于频繁 fork/exit 或线程争锁,内核调度开销已吃掉可观算力 -
wa > 20%:宿主机磁盘或网络后端可能过载,虚拟机本身 CPU 没事,但卡在等数据
注意:vmstat 第一行是系统启动以来平均值,没参考价值;从第二行起才是实时采样。别拿第一行判断当前负载。
为什么 top 显示 CPU 很低,但服务却卡顿
因为 top 默认只显示用户态 + 内核态时间,而虚拟机中大量时间花在“等待宿主机调度”上——这部分被归为 id(idle),但它不是真空闲,是被 vCPU 抢占机制挂起的“伪空闲”。
验证方法:
- 按
1展开多核视图,看是否某些 vCPU 长期id=100%而另一些跑满——这是 vCPU 调度不均的典型表现 - 对比
vmstat的in(中断次数)和cs:若in很低但cs极高,大概率是应用层线程模型有问题,不是宿主机瓶颈 - 检查
/proc/vmstat中的pgmajfault:数值持续上升说明频繁缺页,可能内存配额不足或 swap 被启用
虚拟机里 top 的 %CPU 是“vCPU 时间占比”,不是物理 CPU 占比,不能直接对标物理机指标。
htop 在虚拟机里反而容易误导人
htop 的树状视图和彩色进度条看着直观,但在虚拟化环境下会掩盖两个关键事实:它不显示 vCPU 抢占延迟,也不区分 guest 和 host 的 I/O 等待。
实际使用建议:
- 装了也别依赖默认视图——进
F2 → display options,勾选Hide kernel Threads和Show custom thread names,避免被ksoftirqd这类内核线程刷屏干扰 - 排序别只用
P(CPU%):按T(运行时间)更能发现长期卡在S(sleep)状态却迟迟不唤醒的进程,常是宿主机资源受限导致 - 禁用
htop的“内存柱状图”:虚拟机内存统计受 balloon driver 影响,htop读的/proc/meminfo可能滞后,不如free -h看available列可靠
很多运维习惯性用 htop 杀进程,但在虚拟机里,k 键杀掉一个进程后,若宿主机 CPU 或内存仍紧张,新进程照样被调度器掐脖子——问题不在进程本身。
真正该定期查的三个文件
图形化工具再好,也是对 /proc 下原始数据的封装。虚拟机性能问题往往藏在这些文件的细微变化里:
-
/proc/stat:看cpu行的第 5 列(iowait)和第 10 列(guest_nice)。后者非零说明有容器或 KVM 内部调度开销,不是你的进程写的代码问题 -
/proc/vmstat:重点关注pgpgin/pgpgout(页入页出速率)和pgmajfault。连续 5 秒pgmajfault > 1000,基本可判定内存配额不足或 NUMA 绑定失效 -
/sys/fs/cgroup/cpuacct/下对应 cgroup 的cpuacct.usage_percpu:如果你用了 docker 或 systemd slice,这里能确认是不是某个容器偷偷占满单个 vCPU
这些文件不需要“监控平台”,写个 3 行 shell 就能定时抓取:echo "$(date): $(awk '/^cpu / {print $6}' /proc/stat)" >> iowait.log。复杂点的瓶颈,永远藏在原始计数器的斜率里,不在颜色进度条上。