上传时VPN为何变慢:排队延迟
数据包排队等待时,即使传输很快,通话也会卡顿。在责怪VPN端点之前,先比较空闲与有负载时的往返时间。
备份开始上传,传输计数器看起来正常,视频通话却变得一塌糊涂。链路并不像那个数字所暗示的那样缺少带宽;数据包正在某处排队,交互型数据包排在批量数据后面。这就是排队延迟,通常称为缓冲区膨胀。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_codelshow 命令报告当前规则以及积压和丢弃计数,从而告诉你这个接口是瓶颈,还是仅仅在转发流量。用公平排队算法替换根规则,短流就能轮流获得自己的机会,而不是与批量数据共享一个先进先出队列。当路由器是瓶颈时,把它应用在路由器的 WAN 接口上,而不是习惯性地用在隧道设备上。保留之前的配置,并重新测试有负载时的响应能力和传输速率,因为批量速率略低换来可用的通话是值得的。
隧道改变了什么,又隐藏了什么
VPN 增加了加密和又一跳,同时也对隧道外的设备隐藏了各个流。当上游设备提供按应用区分优先级时,这一点很重要,因为它看到的是加密数据包,而不是原始对话。自行终止隧道的路由器有不同视角和工作负载,可以在内部进行分类。两种布置都不能消除接入链路上的队列,而延迟通常正是在那里累积。
如果延迟不随负载变化,就停止调整队列,去看看别处:Wi-Fi 状况、数据包大小问题,或者一条糟糕的出口路径。没有测量就应用队列设置,只会把谜团挪个地方。