凌晨两点的促销流量把订单接口的 p99 拖到了 4 秒。监控面板上,8 核虚机的 CPU 使用率只有 62%,内存还剩一半,load average 却从 1.2 跳到 11。翻到 vmstat,st 列悄悄爬到了 18%。这时客服多半回你一句“配置够用,是你业务自己的问题”可真实原因,也许只是宿主机上挤了太多邻居。
如果你正在选机器,或者想先把线路和配置跑通再谈长期方案,可以先看看这几家的线路说明和技术参数:浪浪云(全球云服务器),先看清带宽线路、流量策略和退款条款,再决定要不要迁。
这类问题最难的不是把数据采上来,而是判断是谁在抢。同样是 load 高、同样是调度变慢,超售、虚机内部超配、突发流量三种成因的处置路径完全不同:前两者要动资源或换宿主机,后者只需限流削峰。混淆它们的典型后果是加了一倍机器,延迟纹丝不动。
如果你正在选机器,或者想先把线路和配置跑通再谈长期方案,可以先看看这几家的线路说明和技术参数:浪浪云(全球云服务器),先看清带宽线路、流量策略和退款条款,再决定要不要迁。
一、先把偷取时间、运行队列、调度延迟的口径分清
偷取时间是虚拟化特有的账本。/proc/stat 的 cpu 行有八个累加量:user、nice、system、idle、iowait、irq、softirq、steal,第八个就是 steal,表示 vCPU 被 hypervisor 收回去跑别的租户任务的时间,只在虚拟化下才非零。两点采样做差即可:st% = Δsteal / Δtotal × 100。vmstat 的 st 列、top 的 %st 与它同源,三者对不上,说明你采到了不同的容器或 cgroup 视图。
运行队列不是 load average。load 是可运行任务数的指数移动平均,还混入不可中断睡眠;真正的瞬时队列是 /proc/stat 里的 procs_running(等 CPU 或正在跑的进程数)与 procs_blocked(等 IO 的进程数)。procs_running 长期大于 vCPU 数,才说明 CPU 真不够。
调度延迟是进程处于 runnable 却没拿到 CPU 的等待时间。系统级看 /proc/schedstat 的 run_delay 与 wait_time(纳秒累计),进程级看 /proc/<pid>/sched 的 nr_wait、wait_sum、se.sum_exec_runtime。三者分别回答:时间被谁拿走、有多少人排队、排队等了多久。

二、一段固定窗口的采样,把三种成因劈开
先固定方法再谈结论。取 300 秒窗口、1 秒采样一次,记录 /proc/stat 的 cpu 行、procs_running、/proc/schedstat 的 run_delay 与 wait_time,以及 vmstat 的 r、b、cs 三列。vmstat 1 300 配合 sar -w 1 300 都行,关键是每秒落盘,事后才能与业务时间轴对齐。
然后按判据归类:
宿主机超售:st% 稳定高于 5%,高值区间与业务延迟尖峰重合,同时 procs_running 并不高说明 CPU 不缺,缺的是分给你这台机器的时间。此时加 vCPU 无效,被抢走的是宿主机的整体份额。
虚机超配:st% 接近 0,但 procs_running 长期大于 vCPU 数,schedstat 的 run_delay 快速增长,vmstat 的 cs 列高得离谱。这是 vCPU 数超过物理核数后,同一颗物理核上多个虚机互抢时间片,属于“自己人抢自己人”,表现为调度延迟而非 steal。
突发负载:st 与 run_delay 的尖峰只有几秒到几十秒宽,随后自行回落,且与慢查询、GC、批处理日志时间吻合。工作量真的涨了,优先做限流、排队与异步化。

三、四个最容易踩的坑
容器里 st 恒为 0。部分 lxcfs 或托管面板会裁剪 /proc/stat,这时读不到 steal 不代表没有争用,改看宿主机侧指标,或向供应商索要宿机 steal 曲线。
信用机制藏起尖峰。有些 hypervisor 用 CPU credit/burst 模型,未触底时 steal 显示为 0,额度耗尽后才剧烈抖动。只看一分钟均值必然漏判,要看完整的 credit 消耗曲线。
steal 高不等于超售。宿主机跑批、备份、实时迁移、频率调整,同样会抬高 steal。结论必须与 run_delay、procs_running 一起看,单指标定罪容易背锅。
采样太慢或太粗。vmstat 60 会把五秒尖峰抹平,只记均值则掩盖尾部。另外磁盘慢会让大量进程卡在不可中断睡眠,load 一起飙升,看着像 CPU 争用,实则是 IO 瓶颈,要看 b 列与 procs_blocked。

四、从结论到动作
判定为超售:带采样日志向供应商索要宿机 steal 与 credit 数据,要求迁移到不同宿主机或可用区,必要时换独占实例。判定为虚机超配:把 vCPU 数压到不超过物理核数,或升级独享规格。判定为突发:加限流、引入消息队列削峰、给热点数据做缓存预热。
不论哪种结论,都要把 st、procs_running、run_delay 按 10 秒粒度长期留存。用 ServLlama 这类轻量监控脚本只采这几项并落成 CSV,就能把“机器慢”与“业务慢”精确对齐,不必每次手工翻面板。
可直接照做的排查清单
- 固定 300 秒、1 秒间隔采样,保存 /proc/stat、/proc/schedstat 与 vmstat 的 r/b/cs 三列。
- 计算窗口内 st% 与 run_delay 增长率:两者都高才怀疑宿主机;只有 run_delay 高且 procs_running 大于 vCPU 数,考虑虚机超配。
- 对齐业务时间轴,确认尖峰是否落在慢查询、GC、批处理窗口内。
- 确认采样视图未被容器裁剪,必要时索取宿主机侧 steal 与 CPU credit 数据。
- 区分 steal 与宿主机运维动作(迁移、备份、跑批)造成的临时抬升。
- 排障期间别急着加 vCPU,先看 procs_blocked 与磁盘延迟,避免把 IO 瓶颈当 CPU 问题修。
- 处置后复采同样窗口,验证 st% 或 run_delay 回落,再关闭变更。


喜欢
顶
难过
囧
围观
无聊



