我写这篇文章,不是为了给 AVA Hosting 做负面评价。
这只是我作为开发者的一次普通工作经历:服务器表现异常,几个最常见的解释都对不上,最后 Linux 的指标告诉了我真正发生了什么。
我使用的是一台小型 AVA Hosting KVM VPS:
1 vCPU
2 GB RAM
25 GB NVMe上面运行着正常的生产 workload。Nginx 正常运行,backend 也正常运行,还有可用内存,磁盘也没有满。
但服务器就是处理不过来。
于是我在正常生产流量下进行了 60 秒的被动监测。没有运行 stress test,没有制造 HTTP flood,也没有执行 disk benchmark。
结果如下:
vCPU count: 1
Average CPU user: 52.52%
Average CPU system: 8.07%
Average CPU softirq: 6.69%
Average CPU steal: 32.73%
Average CPU iowait: 0.00%
Average CPU idle: 0.00%
Maximum runnable queue: 11真正改变诊断方向的数字是 32.73% CPU steal。
为什么这个结果让我意外
AVA Hosting 目前对其 VPS 使用了 “Guaranteed resources — no sharing” 这样的宣传语。其 VPS 页面还把 vCPU 描述为 fixed 或 dedicated allocation,并表示性能不应受到其他客户影响。关于 Linux VPS 的说明甚至更明确:同一 host 上其他 tenant 的 CPU-intensive workload 不会给你的 instance 带来 steal time。另一个页面则表示,CPU steal 会在 hypervisor 层被消除。
这些都不是模糊的宣传语。它并不是只写着 1 vCPU,却完全不说明 CPU 如何分配的 VPS。AVA 明确宣传自己可以避免的,恰恰就是 Linux 在我的 VM 内部似乎正在记录的那种 CPU contention。
CPU steal 到底是什么
steal 是 Linux 在虚拟化环境中常见的 CPU 指标。它表示 guest 明明有可运行任务,但 virtual CPU 实际上没有获得执行的时间。
这和应用程序单纯把 CPU 用满不是一回事。如果我看到 user/system 接近 100%、steal 为 0%、idle 为 0%,我会认为只是 workload 需要更多计算资源。
但这次,大约三分之一的 CPU 时间被记在了 steal 上。
从 guest 内部,我看不到 AVA 的 hypervisor,也不知道 physical node 的负载、相邻 VM 数量、CPU pinning 策略或 overcommit ratio。我能看到的是 Linux 向 VM 报告的事实:明明还有任务等着执行,vCPU 却反复没有运行。
这不是一秒钟的偶发尖峰
如果只是一个很难看的 CPU sample,我不会轻易下结论。因此我连续监测了 60 秒,并且刻意没有运行 stress test、人工 HTTP flood 或 disk benchmark。
逐秒数据反复出现类似情况:
%usr %sys %soft %steal %idle
53.54 10.10 5.05 31.31 0.00
56.44 6.93 5.94 30.69 0.00
51.52 7.07 6.06 35.35 0.00
55.45 6.93 5.94 31.68 0.00
51.49 8.91 5.94 33.66 0.00
52.53 7.07 7.07 33.33 0.00
52.48 6.93 7.92 32.67 0.00接近监测结束时,模式仍然没有变化:
50.98 10.78 6.86 31.37 0.00
48.48 8.08 9.09 34.34 0.00
55.00 5.00 7.00 33.00 0.00整个周期的平均值:
user: 52.52%
system: 8.07%
softirq: 6.69%
steal: 32.73%
iowait: 0.00%
idle: 0.00%所以这不是短暂的 scheduling anomaly。在这一分钟的大部分时间里,steal 都保持在约 30% 或更高,而 CPU idle 始终为 0。
为了更直观地理解,1 分钟的 32.73% 大约是 19.64 秒。这并不是说 VPS 连续卡死了 19.64 秒,而是许多 vCPU 没有被 schedule 的短时间段累计起来,大约达到了这个数字。
Backend 的队列始终消不下去
CPU 问题在应用层也很明显。监测开始前,backend 的 listen queue 是:
Recv-Q: 168
Send-Q: 51160 秒后:
Recv-Q: 166
Send-Q: 511168 和 166 本身并不重要。重要的是,队列几乎没有减少。应用有整整一分钟追赶积压请求,但依旧没能赶上。
同时还有大量 CLOSE-WAIT 连接。仅凭这一点,我不会把责任归给 host,因为应用自身的 connection handling 同样可能产生这种状态。但整体情况非常一致:
1 vCPU
32.73% steal
0% idle
~99% CPU pressure
elevated runnable queue
backend queue not draining服务器还活着,但显然并不健康。
RAM 和磁盘并不是明显的瓶颈
我也检查了常见原因。内存情况:
RAM total: ~1.9 GiB
RAM available: ~959 MiB
Swap total: 2 GiB
Swap used: ~33 MiB仍然有相当多可用内存,也没有明显的 OOM 事件可以解释这种表现。
文件系统:
24 GB total
14 GB used
9.4 GB available
60% used平均 CPU I/O wait 是 0.00%。与此同时,CPU pressure 一直接近 99%,单 vCPU VM 的 load average 约为 3.5–4,runnable queue 最大达到 11。
所有指标都指向同一个方向:机器缺少可用的 CPU 执行时间,而不是明显卡在 RAM 或 storage 上。
与 AVA 宣传之间的矛盾
这是整个经历中我觉得最值得讨论的地方。
AVA 说 “Guaranteed resources — no sharing”,并表示其他客户不应影响你的性能。Linux VPS 说明称其他 tenant 不会带来 steal time,另一个页面又表示 CPU steal 会在 hypervisor 层被消除。
而我的 AVA VPS 显示:
Average CPU steal: 32.73%从 VM 内部,我无法证明这种情况究竟为什么发生。我不能证明存在故意 overselling,不能确认某个具体的相邻 workload,也无法还原 AVA host 侧的 CPU 配置。
我也没有声称所有 AVA Hosting VPS 都会这样。我测试的只是一台 VPS。
但我可以明确说,我测到的行为与这些具体的 CPU isolation 宣传非常难以同时成立。对这篇文章来说,这已经足够。
为什么我没有升级
最直接的办法当然是购买更多 vCPU。
如果 VPS 几乎没有 steal,而我的应用只是把一个 core 用满,那么升级完全合理。但我观察到的 CPU 时间里,大约有三分之一属于 steal。
在弄清楚为什么第一颗 vCPU 的大量执行时间已经被报告为 unavailable 之前,我不想再为额外的 virtual CPU 付钱。因此我取消了 VPS,并申请退款。
AVA 很快退回了全部款项
这一部分体验是好的。
AVA Hosting 全额退款了。退款处理得很快,也没有花几天时间跟我争论 CPU 测量结果。我解释了问题,要求退款,他们就把钱退了回来。
这一点我很感谢。
所以我的经历其实有两个彼此独立的结论:我拿到的 VPS 确实存在严重的 CPU availability 问题,同时 AVA 的退款处理也很合理。两者都是真的。
我最终学到的东西
现在我不会只看 1 vCPU / 2 GB RAM / NVMe / KVM 这样的规格来判断一台 VPS。这些数字告诉我系统 provision 了什么,却不能告诉我在真实 workload 下 CPU 是否能稳定、可预测地获得。
现在拿到新的 VM 后,我很早就会检查:
mpstat 1 60
vmstat 1 60
cat /proc/pressure/cpu
ss -ltnp
free -h
df -h
iostat -xz 1 60这次 AVA Hosting 经历给我的最大教训,并不是 1 vCPU 一定太少。真正重要的是:进程仍在运行、RAM 还有余量、磁盘看起来正常,并不代表底层没有完全不同的问题。
在我的案例里,Linux 把问题展示得非常清楚:
CPU steal: 32.73%
CPU idle: 0.00%
CPU pressure: ~99%AVA Hosting 宣传 CPU 资源不共享,并表示相邻 workload 不应造成 steal。我的 VPS 报告出的情况并不是这样。
我取消了这台 VPS。AVA 很快、没有争论地退回了全部款项。
这次 debugging 的一天,也就到这里结束了。