返回博客
2026年8月31日Sergei Solod8 分钟阅读

我的 FDCServers VPS 在传输超过 3 TB 流量后一直正常,后来磁盘读取却开始需要 18 秒

我的 FDCServers VPS 起初可以正常处理真实流量,并已传输了超过 3 TB 的数据。随后,普通 workload 开始触发严重的虚拟磁盘 stall:CPU iowait 达到 100%,Linux I/O pressure 接近 100%,读取延迟最高 18.7 秒,flush latency 超过 53 秒。

FDCServersVPSLinux磁盘 I/ODevOps

我写这篇文章并不是为了给 FDCServers 写一篇负面评价,也不是想告诉别人应该还是不应该购买他们的 VPS。我经历的是一台服务器、一个 workload 和一系列特定问题。仅凭这些不足以评价整个托管服务商。

这只是我作为开发者日常工作中的一次故障排查。VPS 此前已经正常运行了一段时间,并且传输了超过 3 TB 的流量。随后,原本正常的 workload 开始造成极其严重的延迟。页面可能很久都没有响应,甚至直接 timeout。最开始我怀疑的都是常见原因:application、Nginx、memory、network、connection limit,或者单纯负载太高。但 Linux metrics 指向了另一个方向。

这台 VPS 并不是从一开始就很慢

在故障间歇期,机器完全可以表现得非常健康。在一个正常时段,没有任何 process 处于 D-state,CPU iowait 约为 0%,disk latency 大约为 2–4 ms,I/O PSI 几乎为零:

D-state processes: 0
CPU iowait:        ~0%
disk latency:      ~2–4 ms
I/O PSI some:      0.04
I/O PSI full:      0.04

如果我只在这个时间点登录,然后查看 topfree -hdf -hsystemctl status nginx,我很可能会得出 VPS 一切正常的结论。随后正常 workload 恢复,机器的状态却会迅速恶化。

18.7 秒的读取延迟改变了排查方向

最有代表性的 iostat sample 之一是:

r_await = 18744 ms
f_await = 53561 ms
aqu-sz  = 128.54
util    = 100.10%
read    = 88 KB/s

这些数字必须放在一起看。已经完成的读取平均耗时约 18.7 秒,flush latency 约为 53.6 秒,平均 I/O queue 超过 128,而实际有效的读取 throughput 只有 88 KB/s。这不是磁盘因为高速处理大量数据而繁忙,而是 storage path 把大量时间花在等待 operation 完成上。

iowait 和 PSI 显示了系统级 I/O pressure

在最严重的阶段,vmstat 显示有 4–9 个 blocked process,CPU iowait 约为 97–100%,CPU idle 为 0%。iowait 并不意味着 application 占满了 CPU,而是说明本来可以继续执行的工作正在等待 outstanding I/O 完成。

Linux Pressure Stall Information 让情况更加清晰:

I/O PSI some avg10 = 99.14
I/O PSI full avg10 = 95.55

在后续复现中,full 接近 98%。Disk utilization 告诉我 device 是否繁忙;PSI 则告诉我 workload 因为该 resource 被阻塞到了什么程度。持续处于 95–98% 的 I/O pressure 并不是轻微的性能下降。

D-state 和 kernel stack 指向 application 之下的层级

接下来我查看了具体有哪些 process 被阻塞。同一时间,我能看到 jbd2systemd-journald、Nginx worker、Nginx cache process 以及其他 filesystem activity 都处于 D-state。如果只有我的 application 卡住,我会继续查 application;但当 Nginx、system journal 和 EXT4 journal 同时被阻塞时,storage 就成了最明显的共同依赖。

EXT4 journaling path 中包括:

wait_on_buffer
jbd2_log_wait_commit
jbd2_journal_commit_transaction

Nginx worker 则卡在普通的文件读取路径:

folio_wait_bit_common
filemap_read
generic_file_read_iter
ext4_file_read_iter
vfs_read
pread64

有一次 kernel 直接报告某个 Nginx task 已经 blocked 超过 122 秒。此时 Nginx 仍然可能显示为 active,但这并不意味着它的 worker 能够完成实际工作。running 与健康运行是两回事。

3 ms 的 backend 响应把 application 与 filesystem path 分开了

最干净的一组对比来自 Nginx 和本地 application backend。通过 Nginx 的 request 因 connection 或 TLS timeout 返回 HTTP=000,而直接请求 backend 大约 3 ms 就完成:

connect = 0.000423 s
TTFB    = 0.003063 s
total   = 0.003139 s

这个测试里具体的 HTTP status 并不重要。Backend 接受了 connection,处理 request,并几乎立刻生成 response。与此同时,Nginx worker 明确卡在 EXT4 read 上。这把 application 本身的正常执行与前面依赖 filesystem 的路径区分开了。

问题能够复现,也可能很快再次消失

一次复现前,机器状态正常:

HTTP:          200
D-state:       0
CPU iowait:    3%
r_await:       ~1.18 ms
I/O PSI full:  ~2.95%

大约半分钟后:

D-state:       4
CPU iowait:    91%
CPU idle:      0%
I/O PSI some:  86.11%
I/O PSI full:  78.02%
r_await:       236.50 ms
HTTP:          000

之后 CPU iowait 达到 96–100%,I/O PSI full 接近 98%,HTTPS queue 达到 512,HTTP 检查依旧失败。相比一句 VPS 感觉很慢,这些数据有用得多。

当我移除 workload 后,反向变化也可以很快发生:

D-state:      0
CPU iowait:   6%
r_await:      ~0.98 ms
queue depth:  ~0.07
HTTP:         200

这就是 intermittent storage problem 难以事后调查的原因。Provider 在恢复后查看服务器时,确实可能看到完全正常的 latency,但这并不能解释十分钟前发生了什么。因此,精确的 UTC timestamp 变得非常重要。

两个可能误导人的 metric:await=0 和可用磁盘空间

在一些严重阶段,我看到 r_await = 0,但与此同时 iowait 很高,process 在 D-state,request 仍然 in-flight,而且几乎没有 read 完成。Latency statistics 是基于已经完成的 I/O 计算的。如果某个 operation 一直卡住,没有在 sampling interval 内完成,它就无法进入已完成 operation 的平均 latency。因此,0 并不总意味着磁盘瞬间完成了操作。

我也考虑过 disk fullness。后来 filesystem 确实比我通常允许的更满,但同一类 failure 在 root filesystem 只使用约 24% 时就已经出现。当时大约有 1.2 GiB RAM available,inode usage 约为 5%,network interface 也没有 error 或 dropped packet。因此,磁盘空间占用无法解释整个 incident。

我能证明什么,又不能证明什么

从 VPS 内部,我能观察到 application、Linux VFS、EXT4 和 virtual block device。再往后就是 provider 的 infrastructure:virtualization、distributed storage、storage network、physical device、scheduling,以及其他 guest 无法直接检查的层级。

因此,我不能诚实地声称某块具体的 physical SSD 已损坏,也无法把某个特定 storage node、network path 或 virtualization component 指定为 root cause。

我能够有充分证据支持的结论更窄:提供给我的 Linux guest 的 virtual storage path 多次进入一种状态,在这种状态下,普通 filesystem I/O 需要数秒才能完成,甚至无法在合理时间内完成。 依据包括 iostat、PSI、D-state、kernel wait stack、EXT4/jbd2 wait、Nginx filesystem wait、queue depth 和 request timing。这已经足够完成我需要的工程诊断,但不足以确认物理层面的 root cause。

为什么此前超过 3 TB 的流量并不与后来的 stall 矛盾

一开始我也很困惑。如果 storage 有问题,为什么这台 VPS 此前能够成功传输数 TB 数据?

因为 network traffic 和 physical disk I/O 并不是同一个概念。一个 file 可以只从 backing storage 读取一次,随后保留在 Linux page cache 中,再从 memory 被重复提供很多次。因此,网络传输 3 TB 并不代表发生了 3 TB 的 unique physical disk reads。

Infrastructure 的状态也会随时间改变,包括 cache state、storage load、queueing、host placement 和其他 workload。VPS 昨天运行正常,并不能保证今天的 storage behavior 完全相同。

最终,我不再等待更深入的 root cause

我收集了精确 timestamp、vmstatiostat、PSI、blocked-process snapshot、kernel stack、filesystem wait、queue depth 和 HTTP timing。我把这些 diagnostics 发给 FDCServers,并等待 infrastructure level 的进一步解释。

我等了很久。最后决定不再继续等待。从我的角度,做出运营决定所需的信息已经足够:问题可以复现、非常严重、明显发生在 application layer 之下,而物理原因位于我的 VPS visibility 之外。

我申请了退款,FDCServers 把钱退给了我

我向 FDCServers 发送了问题总结和收集到的 diagnostics,要求取消 service 并 refund。他们退款了。

所以这段经历并没有以一场长期的退款争执结束。我等待最终的技术解释,后来决定不再等,把手里的 evidence 发过去并要求退钱。FDCServers 把钱退了回来。

这件事之后,我改变了什么

这次经历最有价值的结果,并不是判断某一家 hosting company 到底好不好,而是改变了我调试慢速 Linux server 的方式。

我依然会使用 topfree -hdf -h,但现在会更早查看:

date -u
uptime
cat /proc/pressure/io
cat /proc/pressure/memory
cat /proc/pressure/cpu
vmstat 1 10
iostat -x 1 10
ps -eo state,pid,ppid,etime,wchan:50,comm,args | awk 'NR==1 || $1 ~ /^D/'
ss -lntp
journalctl -k --since '30 min ago' --no-pager

只要条件允许,我也会分别测试不同 request path:public request、local Nginx、direct backend、filesystem 和 block-device metrics。问题不再只是服务器为什么慢,而是:有用的工作究竟在哪一层停止完成?

只要可能,我会在 reboot 之前先保存 evidence。Reboot 也许能恢复 service,但也会同时抹掉恰恰能够诊断 intermittent incident 的 D-state、PSI、queue 和 latency。

最后

我购买 FDCServers VPS 并不是为了获得一篇托管服务文章的素材。我只是需要一台带宽充足的 server。有一段时间,我确实得到了自己需要的东西:它处理真实 workload,并传输了超过 3 TB 数据。

随后,普通 workload 开始稳定复现 iowait 最高 100%、I/O PSI 接近 100%、read 最长 18.7 秒、flush latency 超过 53 秒、大量 queue、Nginx 卡在 filesystem read,以及 EXT4/jbd2 等待 I/O 的情况。

我始终不知道具体是哪一个 physical 或 host-side component 导致了问题,也没有必要假装自己知道。我确认了 failure 出现的 layer,收集了足以将它和 application problem 区分开的 evidence,停止等待更深入的 root-cause explanation,并要求退款。FDCServers 最终退款了。

这不是对所有 FDCServers VPS 的结论。它只是一个记录充分的提醒:service 可以显示为 active,process 可以显示为 running,但机器仍可能把几乎所有真正有用的时间都花在等待 storage 上。