有一种说法流传很广:加速器通过“更快的线路”来减少延迟。
这句话没说错,却把真正值得琢磨的部分盖住了。物理线路上信号的传播速度被光速锁死,任何设备都越不过这条线。那加速器到底改变了什么?答案不在传输层,而在协议层。
加速器的原理,说白了是改写了端到端通信的协议行为:数据包在物理链路上的传输方式和没加速时不一样——不是传得更快,而是传得更“有效”。而“有效”这个词需要拆开来看,因为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 包原样转发出去,这台机器的角色就和运营商的一台路由器重合了,唯一的差别是它换了条物理路径。真正的’加速‘并不发生在协议本身,而是发生在’选哪条路‘与’丢了怎么补‘这两个决策上。
第一种思路是:加速器在中间节点上给 UDP 做前向纠错编码。发送端在原始数据报之外再附上冗余数据,途中若有丢失,接收端就能靠冗余信息把丢掉的那部分重建出来,不必苦等重传。代价是带宽占用变多;但对实时音视频这类看重延迟的应用来说,等一次重传远比多花一点带宽更难接受。
还有更激进的一种:加速器把 UDP 换成自定义的可靠协议在中间链路上跑,到了对端节点再还原成 UDP。这等于放弃了 UDP 无连接的特性,在中间这一段引入了类似 TCP 的确认与重传。对那些’用着 UDP、其实需要一定可靠性‘的应用,这样做可能是有效的;但对把丢包当作拥塞信号的协议(比如 QUIC),把丢包藏起来反而可能打乱应用层的速率控制逻辑。
还有一层反直觉的地方:抖动确实可能被压下去,排队时间却可能悄悄涨上来。中间节点要做 FEC 编码、要缓冲,这些都要花时间;节点一忙,处理上的开销就可能盖过绕开拥堵省下的那点时间。所以你看到的可能是:RTT 曲线变平了,但底部整体抬高了一点。
代理的拓扑:节点在哪里,比有多少节点更重要
所有加速器本质上都是代理——它们终止一端连接,建立另一端连接。但代理的拓扑结构决定了加速效果的上限。
一个常见的工程选择是“边缘节点 + 骨干网 + 边缘节点”。用户连接到最近的边缘节点,流量通过加速器自建的骨干网传输,然后在目标侧的边缘节点离开,进入公共互联网到达目标服务器。
这类设计的前提假设是:加速器的骨干网比公共互联网更快、更可靠。在部分路径上这个假设成立——尤其是那些要跨过多个运营商对等互联点的长距离路径,因为这些对等点往往是拥堵的高发地带。但在另一些路径上,公网的 BGP 可能已经挑出了足够好的路由,加速器的骨干网并没有额外收益。
决定成败的变量其实是节点摆在哪儿。如果你到加速节点这一截本身就要穿过一个堵着的运营商出口,那么把流量交给它并不能救’第一公里‘。另一端同理——目标服务器若托管在与加速器骨干网没有直连的机房,’最后一公里‘照样得看公网的脸色。
在工程实践中通常会看到,加速效果对“中部路径”的优化最为明显,而对第一公里和最后一公里的控制力较弱。如果用户的本地网络或目标服务器的接入网络是瓶颈,加速器能做的事情非常有限。
判断一个加速服务是否适用于特定场景,最直接的方式不是看宣传的节点数量,而是测量你的流量实际经过了哪些网络边界。节点数量多意味着选择多,但不意味着自动选择了最优路径.
# 通过加速器访问目标,观察路径变化 mtr -r -c 10 目标IP # 对比直连路径 mtr -r -c 10 --address 本地IP 目标IP
如果你发现加速后的路径确实绕开了某个经常出现拥塞的AS边界,那么加速有效。如果加速后的路径在到达加速节点之前已经经过了那个边界,那么加速器没有帮上忙。
误判:加速 vs. 路由变化
还有一种情况容易被误判为加速器的效果:本地ISP的路由策略恰好发生了变更。
还有一类归因陷阱:某段时间延迟降了,而那段时间你恰好开着加速工具,于是功劳被算到了工具头上。可真相也许是运营商在此期间因链路故障或成本调整换了出口路由,路径正好绕开了常年拥堵的点。要分辨这两者,就得在切换前后各测一次直连与加速路径——没做对照就没有结论。
还有一种更隐蔽的情形:加速工具用到的 DNS 解析返回了另一个目标 IP。大型服务普遍使用 CDN,不同 IP 对应不同的接入点。如果加速器的 DNS 解析给出了一个离用户更近、或者负载更低的 CDN 节点,那么延迟的下降可能完全来自 DNS 层面的变化,而与加速器的骨干网无关。这正是’看着像加速器,其实是 DNS‘的另一种变体。
要区分这些情况,需要保持一个不变的参照系:固定目标IP,而不是目标域名。用IP进行直连测试和加速测试的对比,才能排除DNS变化的干扰。用域名测试时,你不知道每一次解析返回的IP是否相同。
系统的边界
加速器能改变的是协议行为和中部路径。它不能改变的是光速限制、第一公里链路质量、目标服务器的处理延迟,以及应用层协议自身的交互模式。
边界也得说清楚:如果一款应用的延迟主要卡在服务端的数据库查询或业务逻辑上,传输层再怎么打磨,用户也不会感觉到变化;如果协议设计要求串行多次交互才能完成一次操作(比如连续调好几个 API),加速器能省的只是每一趟的传输时间,交互的趟数它减不掉。
说到底,搞清加速器做不到什么,比搞清它做得到什么更有价值。它不是让网络变快的魔法,而是在一堆约束条件下,用协议中继和路径选择去改变数据流动方向的工程手段。先把边界划出来,再判断它适不适合你这个问题——顺序反了,就变成了拿问题去迁就工具。
