速度测试从来不是在测 VPN 本身。它测的是一条路径,而打开隧道会在第一个字节发出之前就替换掉这条路径的一部分。所以同一台笔记本对某个网站给出健康的数字,对另一个网站却是糟糕的数字,而两端其实什么都没变。把结果当作关于路径的证据来读,而不是给产品打的分。

比较是否有价值,取决于三件事:两次运行是否命中同一个目标、接入网络是否保持不动,以及你是否把延迟和吞吐一起记录了下来。

隧道在第一个字节之前改写了什么

客户端会给每个数据包再套一层头部,于是每个包的可用载荷变小了。这种开销按包计,而不是按传输计,也就是说同一个大文件走隧道比不走隧道需要更多数据包。这类额外开销体现为包数,而不是某个看得见的设置项。

由此有两个结果。用大块数据构造的测试感受到的是按包计的开销,而用大量小请求构造的测试感受到的反而是往返次数。另外,如果路径 MTU 探测在途中某处被挡住,隧道就会停在更小的包长上,吞吐下降的原因和加密算法毫无关系。

上限可以直接观察。在 Linux 上先请求不分片时能通过的最大载荷,然后打开隧道再重复一次:

ping -M do -s 1472 -c 3 203.0.113.10

如果失败,就降到 1,400 再试。只能承载 1,380 字节的隧道是在告诉你,路径更下游有东西压得更紧,客户端再怎么调也抬不起来。

为什么隧道一开,测试服务器就换了地方

大多数工具会根据它看到的公网地址挑选附近的服务器。隧道开启后,那个地址属于出口节点,于是工具可能选到另一个城市或另一个国家的主机。这时你比较的是两个目的地,两者之间的差距里就包含了从出口到测试主机的距离。

在第一次运行之前按名称或 ID 固定服务器,并在之后每一次运行中保持它。如果工具留不住,就选一个你能控制的目标,自己去驱动它: iperf3 -c test.example.net -R -t 20 会把目的地固定住,给出一个能和昨天比较的数字。

只改一个变量,而底层并不止一个

无线是最常见的隐藏变化。笔记本一动信号强度就变,邻居一开始通话信道占用就变,所以隔十分钟在 Wi-Fi 上跑两次,并不算对同一个测试的重复。用有线,或者固定位置并把信号电平记下来,就能去掉大部分这类噪声。在每次运行的开头和结尾记一下信号电平,通常就足以判断两次运行能不能放在一起看。

设备负载也要算进同一本账。只在单核上做加密的客户端,早在链路之前就撞到自己的上限,后台同步则更早撞上。运行时盯着 CPU,并记下还开着什么。电源设置在这里也会咬人,因为用电池的笔记本可能在链路还没接近饱和时就先限制了处理器。

MeasurementWhat it answersWhat it misses
DownloadBulk capacity along the pathAny question about responsiveness
UploadCapacity from client to exitDownload health
RTT to a fixed targetDistance plus queueingWhether capacity is available
Jitter or lossStability under loadHow much the link can carry

要让底层保持不动,而不是对它取平均。三次彼此吻合的运行,比在不同房间做的十次更有说服力。

延迟、丢包和 ICMP 回答的是不同的问题

ping 向一个固定地址发送小探测包,而很多网络会以低优先级回应 ICMP,或者干脆不理。没有回应说明的是探测包本身,而不是应用的包。负载下上升的往返时间通常意味着某个队列在填满,而不是路径变长了。

想知道隧道是否增加了延迟,可以拿同一个目标在开与不开隧道时对比,也可以对比从同一接入网络能到达的两个出口。反复运行探测并观察离散程度,因为平均值恰好会隐藏那种让通话不可用的波动。

回到那件让你觉得慢的事

通话还在断续时指标却变好了,那它回答的是另一个问题。把当初引发排查的那件事重新做一遍,不管是会议、文件共享还是远程桌面会话。如果数字变好而那件事没有变好,瓶颈就在测试从未到达的地方,比如隧道后面的服务器,或者你这边的上行链路。

每次运行都记录设备、接入网络、端点、协议、目标和时间。一次从未连上的运行属于可达性结果,而不是零吞吐,所以把它归到那个标签下,而不是删掉。

下一次比较前的简短清单

固定目标,并写下你为什么选它。记录路径允许的包长,这样以后掉速时有解释可循。让接入网络保持一致,记下 CPU 负载,在相信差异之前先跑三次。

然后只改一处再重复一遍。你能解释清楚的比较,胜过数字更大的那次比较。

相关文章