备份开始上传,传输计数器看起来正常,视频通话却变得一塌糊涂。链路并不像那个数字所暗示的那样缺少带宽;数据包正在某处排队,交互型数据包排在批量数据后面。这就是排队延迟,通常称为缓冲区膨胀。VPN 可能增加自己的队列,但很少单独制造问题。

带宽和延迟是不同的测量

吞吐量回答每秒有多少数据移动,而延迟回答一个数据包穿过路径需要多长时间。饱和的链路可以积压大量数据,却仍报告良好的吞吐量,因为突发结束后队列会以线路速率排空。交互流量最先受害,因为通话每隔几毫秒就需要一个数据包,而不是最终等来一个大文件。因此,只测速测结果会掩盖让你来查看的症状。

也要注意负载下的方向。上传缓冲区满时,即使下载容量闲置,其他一切也会被拖慢。

在有负载时测量往返时间

在安静链路上取一个基线,然后在一项受控传输进行时重复同样的测量。比较两次运行,而不是绝对值。

ping -c 20 -i 0.2 203.0.113.5
dd if=/dev/zero bs=1M count=50 | ssh [email protected] "cat > /dev/null"

第一条命令采样往返时间,第二条无需测速服务即可制造持续上传。基线保持平稳,随后有负载的运行上升数百毫秒,这就是要找的特征。有些网络会降低 ICMP 的优先级,所以把 ping 当作线索,并用应用自身的延迟显示来确认。在按流量计费的链路上保持测试简短,因为可重复的对比比长时间饱和更重要。

把队列移到瓶颈所在处

队列管理只在真正持有积压的设备上才有帮助。在添加规则之前,先检查接口在做什么。

tc -s qdisc show dev eth0
tc qdisc replace dev eth0 root fq_codel

show 命令报告当前规则以及积压和丢弃计数,从而告诉你这个接口是瓶颈,还是仅仅在转发流量。用公平排队算法替换根规则,短流就能轮流获得自己的机会,而不是与批量数据共享一个先进先出队列。当路由器是瓶颈时,把它应用在路由器的 WAN 接口上,而不是习惯性地用在隧道设备上。保留之前的配置,并重新测试有负载时的响应能力和传输速率,因为批量速率略低换来可用的通话是值得的。

隧道改变了什么,又隐藏了什么

VPN 增加了加密和又一跳,同时也对隧道外的设备隐藏了各个流。当上游设备提供按应用区分优先级时,这一点很重要,因为它看到的是加密数据包,而不是原始对话。自行终止隧道的路由器有不同视角和工作负载,可以在内部进行分类。两种布置都不能消除接入链路上的队列,而延迟通常正是在那里累积。

如果延迟不随负载变化,就停止调整队列,去看看别处:Wi-Fi 状况、数据包大小问题,或者一条糟糕的出口路径。没有测量就应用队列设置,只会把谜团挪个地方。

相关文章