揭秘加速器:TCP、UDP与代理如何协作

list 文章目录

有一种说法流传很广:加速器通过“更快的线路”来减少延迟。

这句话没说错,却把真正值得琢磨的部分盖住了。物理线路上信号的传播速度被光速锁死,任何设备都越不过这条线。那加速器到底改变了什么?答案不在传输层,而在协议层。

加速器的原理,说白了是改写了端到端通信的协议行为:数据包在物理链路上的传输方式和没加速时不一样——不是传得更快,而是传得更“有效”。而“有效”这个词需要拆开来看,因为TCP和UDP对它的定义完全不同。

TCP加速:确认不是确认

TCP的设计约束是理解一切加速行为的起点。

TCP需要三个东西才能开始传输数据:SYN、SYN-ACK、ACK。这个三次握手的过程,在一条RTT为200ms的链路上,需要至少200ms才能完成——单向一次SYN,反向一次SYN-ACK,第三个ACK可以携带数据,但连接建立本身消耗了一个RTT。这就是所谓的“冷启动延迟”。

然后,TCP的拥塞控制算法会从一个较小的拥塞窗口开始。每收到一个ACK,窗口增大一点。在一个高延迟链路上,窗口的增长速度受限于ACK返回的速度。如果RTT是200ms,那么每200ms窗口才能增长一次。这意味着,即使链路有充足的带宽,TCP也需要多个RTT才能“探测”到可用带宽并填满它。这就是“慢启动”并非真慢,而是受RTT约束的探测过程。

很多人会误以为加速器“降低了延迟”。更准确的说法是,加速器将长RTT链路分割为多段短RTT链路,让每一段的TCP行为独立运行。

考虑一个场景:用户在北京,目标服务器在洛杉矶。直连RTT大约200ms。加速器在东京部署了一个节点。用户到东京的RTT是60ms,东京到洛杉矶的RTT是110ms。

当用户通过加速器访问目标时,实际上建立了两个TCP连接:用户到东京节点,东京节点到目标服务器。每个连接各自完成三次握手,各自维护独立的拥塞窗口,各自处理重传。

这意味着什么?用户发送的数据,在60ms内就到达了东京节点,东京节点立即返回ACK——这个ACK不是来自目标服务器,而是来自中间节点。用户的TCP栈认为链路延迟只有60ms,拥塞窗口增长速度比直连快三倍以上。数据在东京节点被缓存,然后通过第二条TCP连接发往洛杉矶。

这种设计带来的行为变化是:用户侧感知到的TCP连接建立时间和慢启动过程,都与短RTT链路对齐。但代价是,端到端的语义被破坏了——发送端收到ACK时,数据可能还没离开东京节点。

这就是TCP加速的本质:用空间换时间,用中间缓存换取更快的ACK反馈循环。它没有违反TCP协议,而是在两个独立的TCP连接之间做中继。每一段都是合法的TCP,但整体不再是端到端的TCP。

UDP加速:为什么相同的逻辑不适用

UDP没有连接建立过程,没有ACK,没有拥塞窗口。那么UDP加速在做什么?

如果加速器只是简单地在中间节点转发UDP数据报,那么它实际上只是一个普通的路由节点,除了可能走不同的物理路径外,和ISP的路由器没有本质区别。UDP的“加速”不来自协议层面的优化,而来自路径选择和丢包恢复策略。

有一种设计是,加速器在中间节点对UDP进行前向纠错编码。发送端在原始数据报之外附加冗余数据,如果途中发生丢包,接收端可以用冗余信息重建丢失的数据,而不需要等待重传。这种做法的代价是带宽开销增加,但对延迟敏感的应用(比如实时音视频)来说,等待重传比多消耗带宽更不可接受。

另一种设计更激进:加速器将UDP转换为自定义的可靠协议在中间链路上传输,到达对端节点后再还原为UDP。这样做等于放弃了UDP的无连接特性,在中间段引入TCP-like的确认和重传。对于那些“用UDP但实际需要一定可靠性”的应用来说,这可能是有效的;但对于依赖丢包作为拥塞信号的协议(比如QUIC),这种隐藏丢包的做法可能干扰应用层的速率控制逻辑。

这里有一个容易被忽略的反直觉现象:UDP加速可能让延迟抖动降低,但引入了额外的排队延迟。因为中间节点的FEC编码和缓冲处理需要时间,如果加速节点的负载较高,这部分处理延迟可能超过绕开的拥塞路径所节省的时间。用户看到的RTT更稳定了,但基础延迟反而略增。

代理的拓扑:节点在哪里,比有多少节点更重要

所有加速器本质上都是代理——它们终止一端连接,建立另一端连接。但代理的拓扑结构决定了加速效果的上限。

一个常见的工程选择是“边缘节点 + 骨干网 + 边缘节点”。用户连接到最近的边缘节点,流量通过加速器自建的骨干网传输,然后在目标侧的边缘节点离开,进入公共互联网到达目标服务器。

这个设计的核心假设是:加速器的骨干网比公共互联网更快、更可靠。这个假设在某些路径上成立——特别是那些跨越多个ISP对等互联点的长距离路径,因为这些对等点往往是拥塞的高发区域。但在另一些路径上,公共互联网的BGP可能已经选择了足够好的路由,加速器的骨干网没有额外收益。

节点位置是这个系统中最关键的变量。如果用户和加速节点之间的路径本身就经过一个拥塞的ISP出口,那么将流量发给加速节点并不能解决这第一公里的问题。类似地,如果目标服务器托管在一个和加速器骨干网没有直连的机房,那么最后一公里仍然暴露在公共互联网的波动中。

在工程实践中通常会看到,加速效果对“中部路径”的优化最为明显,而对第一公里和最后一公里的控制力较弱。如果用户的本地网络或目标服务器的接入网络是瓶颈,加速器能做的事情非常有限。

判断一个加速服务是否适用于特定场景,最直接的方式不是看宣传的节点数量,而是测量你的流量实际经过了哪些网络边界。节点数量多意味着选择多,但不意味着自动选择了最优路径.

bash
# 通过加速器访问目标,观察路径变化
mtr -r -c 10 目标IP

# 对比直连路径
mtr -r -c 10 --address 本地IP 目标IP

如果你发现加速后的路径确实绕开了某个经常出现拥塞的AS边界,那么加速有效。如果加速后的路径在到达加速节点之前已经经过了那个边界,那么加速器没有帮上忙。

误判:加速 vs. 路由变化

还有一种情况容易被误判为加速器的效果:本地ISP的路由策略恰好发生了变更。

假设用户在某个时间段观察到延迟下降,碰巧是在使用加速工具之后。直觉会归因于加速工具。但同一时间段,ISP可能因为链路故障或成本调整而切换了出口路由,导致路径绕开了常年的拥塞点。如果用户没有在切换前后同时测量直连路径和加速路径,就无法区分这两种可能性。

更隐蔽的情况是,加速工具使用的DNS解析返回了不同的目标IP。很多大型服务使用CDN,不同IP对应不同的接入点。如果加速器的DNS解析返回了一个离用户更近、或者负载更低的CDN节点,延迟下降可能完全来自DNS层面的变化,而不是加速器骨干网的贡献。这就是“看似是加速器,其实是DNS”的变体。

要区分这些情况,需要保持一个不变的参照系:固定目标IP,而不是目标域名。用IP进行直连测试和加速测试的对比,才能排除DNS变化的干扰。用域名测试时,你不知道每一次解析返回的IP是否相同。

系统的边界

加速器能改变的是协议行为和中部路径。它不能改变的是光速限制、第一公里链路质量、目标服务器的处理延迟,以及应用层协议自身的交互模式。

如果一个应用的延迟主要来自服务端的数据库查询或业务逻辑处理,那么无论传输层怎么优化,用户体验都不会有可感知的改善。如果一个应用的协议设计要求多次串行交互才能完成一次操作(比如多次API调用),那么加速器只能优化每次交互的传输延迟,而不能减少交互次数。

理解加速器的边界,比理解它的功能更重要。它不是让网络变快的魔法,而是在特定约束下,通过协议中继和路径选择来改变数据流动方式的一种工程手段。确认了它的边界,才能判断它是否适合你的问题——而不是反过来,用你的问题去验证它的功能。

作者

狗急加速器技术团队