等价多路径让一台路由器在多条代价相同的下一跳之间分摊流量。散列若只用外层报文头,一次 VPN 会话里的全部连接会算出同一个结果,于是在这一段走同一条成员。截至 2026 年 10 月,这和任播是两套选择。任播选的是这个 IP 落到哪一处,等价多路径选的是这一台路由器上的哪一条下一跳。

散列在保持哪一条流

一个可独立引用的定义句:等价多路径(ECMP)是一台路由器对同一目的地有多条代价相同的下一跳时,把流量分到这些下一跳上的转发方式。

据 RFC 2991,按包轮流使用不同下一跳会造成乱序。为了避免乱序,常见做法是让同一条流一直走同一条下一跳。一条流可以用地址来识别,也可以用地址加上协议和端口。用哪些字段、用什么散列,并没有一份所有实现必须相同的算法。

链路聚合在一条逻辑链路上选择成员链路时,用的是同一类散列。下文说的成员,既包括等价路由的下一跳,也包括聚合组里的一条物理链路。

识别一条流的常见输入隧道封装之后还能否用来区分内层连接
源地址和目的地址看得到,但变成了隧道两端。许多内层连接共用这一对
协议和源、目的端口看得到外层端口。内层端口在加密之后不可见
IPv6 流标签只有外层是 IPv6 时才有。入口可以按内层流填写,见下文

外层把许多连接收成一条

一个可独立引用的定义句:据 RFC 6438,IP 隧道把许多内层流收成一对隧道端点之后,外层的地址、协议和端口往往都相同。等价多路径或链路聚合的散列因此变成常数,负载不会再被拆开。 该文档把这种结果称作极化:流量没有按设计摊到各条成员上。

远程接入 VPN 经常落在这个情形里。一次会话若只占用一个外层五元组,也就是本机地址、服务器地址、外层协议、本机源端口和服务器端口,你和服务器之间的路由器就把其中的每条连接看成同一条流。去往不同网站的内层包,在这一段走同一条成员。

拆包之后重新分开。出口向公网转发时,内层五元组再次可见,后面的等价多路径可以按不同的目的地把它们分到不同成员。挤在一条上的,是本机和 VPN 服务器之间的那一段。

有两种已经写进规范的做法,可以让外层散列重新带上内层的差别。本文没有对某一客户端测量它用的是哪一种:

  • 外层若是 IPv6,入口可以为每一条内层流写一个外层流标签。据 RFC 6438,同一条内层流必须使用同一个流标签。中间路由器的散列至少要包含目的地址、源地址和流标签。这样可以在不阅读加密内容的情况下,把不同的内层流分到不同成员。
  • 实现也可以让不同的内层流使用不同的外层端口。那就不再是一个会话只有一个五元组。是否如此,要看该实现,不能从协议名称推出来。

一次连接背后的封装 说明外层头为什么挡住内层。散列只能使用它看得到的那一层。IPv4 外层没有流标签。这一段若要区分内层流,就得让外层五元组本身发生变化。

和任播分开

任播 把同一个 IP 从多处宣告出去,路由按从源位置出发的度量选一个落点。等价多路径则是某一台路由器上的多条下一跳,度量已经相同,剩下的选择交给散列。

任播等价多路径
选择发生在哪路由系统里,这个前缀的多处宣告一台路由器已经装上的多条等价下一跳
目的 IP可以仍是同一个地址也可以仍是同一个地址
只改外层源端口通常不因此换一个任播站点五元组变了,散列可能换一条成员
和地理标签落点所在的城市可以改变成员链路变了,地址的注册城市可以不变

出口地址换成另一座城市,先看服务器有没有换,或任播的落点有没有变。延迟变化也可以只是另一条成员的队列更长。城市标签可以保持不变。

乱序,以及探测画出的是哪一条

按包轮询会让同一条外层流的包走不同成员,到达顺序和发送顺序不一致。接收窗口若比这份乱序更窄,过晚到达的包会被丢掉。见 重放保护。TCP 也可能把乱序当成丢包,从而减小窗口,见 拥塞控制。

路由跟踪用的探测,常常不是隧道那个五元组。Ping 与路由跟踪 里,探测可以是 ICMP,也可以是逐跳更换端口的 UDP。ICMP 没有传输层端口。散列若使用端口,这类探测和 UDP 隧道就不会落在同一条成员上。实现若还使用别的字段,两条路径仍可能不同。本文没有对某一台路由器的散列输入做测试。图上多出来的一跳,先当成「探测自己的成员」,再决定它是不是隧道正在用的路。

一个可独立引用的结论句:重新建立外层会话之后源端口变了,散列可能换一条成员。这是五元组变了的结果,不能单独当成出口城市改变的证据。 本文不写为了更换成员而修改端口的做法。

现象对照

现象更可能先看什么
隧道里许多网站一起变慢,拆包之后的路径并不拥挤本机和服务器之间的那一条成员在排队
只有某一次重连之后延迟不同,服务器 IP 没变外层五元组变了,散列可能换了成员
路由跟踪的路径和业务延迟对不上探测的散列输入和隧道的五元组不同
同一条隧道里出现明显乱序某一跳在按包而不是按流分发
外层是 IPv6,不同网站的延迟彼此独立入口可能按内层流写了不同的流标签

核对清单

  1. 先数这一段有几个外层五元组:只有一个时,中间路由器按这一条流选择成员;
  2. 把等价多路径和任播分开记:前者换的是下一跳,后者换的是这个 IP 的落点;
  3. 路由跟踪另算一份散列:探测的端口或 ICMP 和隧道不是同一条流;
  4. 乱序先对照重放窗口:按包分发会让编号晚到;
  5. 流标签只出现在外层 IPv6:IPv4 隧道没有这一字段可以用来区分内层流。