互联网流量是如何路由的

posts/how-internet-traffic-is-routed

前几天看到群友在调试网络,给我看了一下 nexttrace 的输出,顺便给我讲了讲 BGP 网络路由的原理,以及为什么网络请求会绕远,于是我打算写这篇文章记录一下。

AS 是互联网的基本单元

自治系统

互联网不是一个大网络,而是很多个独立网络的拼接。

每个独立网络就是一个 AS(Autonomous System,自治系统):

  • 一个 ISP(如中国电信 AS4134、中国联通 AS4837)
  • 一个云厂商(如阿里云 AS45102、腾讯云 AS132203)
  • 一个大型企业或高校(如 CERNET 教育网 AS4538)
  • 一个 CDN 服务商(如 Cloudflare AS13335)

每个 AS 内部自己决定怎么路由,但跨 AS 的路由需要 BGP 来协调。

1.1.1.1 所在的 1.1.1.0/24 网段由 AS13335(Cloudflare)宣告和管理。一条网络路径,本质上是多个 AS 的组合。

AS 之间的关系

这些 AS 之间是什么关系?这直接决定了流量能不能走、怎么收费。

关系类型描述流量方向是否付费
Customer → Provider客户向提供商购买网络接入双向Customer 付费
Peer ↔ Peer对等互联,互相交换流量仅交换各自及下游客户的流量通常免费
Transit提供中转服务任意方向收费

这些身份在网络公司里长什么样?

阿里云(Customer) ───→ 电信(Provider)
   ↕ Peer                    ↕ Transit
腾讯云(Peer)              NTT(Provider)

以 Cloudflare(AS13335)为例。它对使用 Cloudflare CDN 的企业来说是 Provider,这些企业把流量导向它,由它负责清洗 DDoS、缓存内容、加速访问。但它自己接入全球网络时,又向各地的 ISP 购买带宽和机柜,这时候它是 Customer。同时它在各大互联网交换中心(IX)和 Google、Meta 建立 Peer 关系,直接交换流量,省下 Transit 费用。

中国电信(AS4134)也是一样的多重身份。它是几亿家庭宽带用户的 Provider;但它要触达海外,不可能在每个国家都自建海底光缆,于是向 NTT(AS2914)、Cogent(AS174)等国际骨干网运营商购买 Transit;它和中国联通(AS4837)、中国移动在骨干节点建立 Peer,互相交换各自用户的流量。

Peer 的典型场景是互联网交换中心。阿里云(AS45102)和腾讯云(AS132203)在同一个 IX 接入后,可以直接建立 Peer,互相交换各自云服务器之间的流量,不需要花钱买 Transit。Peer 的边界很清楚,只交换各自及下游客户的流量,不帮对方中转第三方。

这些身份不是固定的,而是看相对谁而言。阿里云向电信买带宽,阿里云是 Customer,电信是 Provider。同一个电信,向 NTT 买国际 Transit 时,电信又变成了 Customer。

这些身份直接决定 BGP 怎么选路。从 Customer 学到的路由优先级最高,因为把流量带给客户是收入。Peer 的路由次之,是免费交换。Provider 的路由优先级最低,因为走 Provider 意味着自己要掏钱买带宽。所以即使 Provider 路径在地理上更短,AS 也会优先把流量导向 Customer 或 Peer。

这些商业偏好最终会通过 BGP 的 LOCAL_PREF 属性落实到路由器的选路策略里。

AS 之间不会无偿转发第三方流量。Provider 不会免费帮 Customer 转发去其他 Peer 的流量;Peer 之间只交换各自的流量,不会帮对方中转。如果 A 和 B 没有直接连接,也没有共同的 Provider/Peer,那它们之间的流量就必须找 Transit。

这个规则解释了为什么路径会绕路。有时候直接连更短,但因为商业关系不允许,只能绕远路找有关系的 AS。

BGP 传播的是可达性

可达性

BGP(Border Gateway Protocol)是自治系统间的路由协议。它在 AS 之间传播可达性信息。

注意:传播的是可达性,不是最优路径。

传播过程

假设 AS100 拥有前缀 192.0.2.0/24,它想让全世界都能访问到这个网段:

  1. AS100 向它的 Provider(比如 AS200)宣告:192.0.2.0/24 可以通过我到达
  2. AS200 收到后,加上自己的 AS 号,继续向它的 Peer 和 Customer 传播:192.0.2.0/24 可以通过 AS200 → AS100 到达
  3. 其他 AS 收到后,继续传播,直到这个前缀传遍整个互联网

最终,每个 AS 的路由表里都会有类似这样的条目:

192.0.2.0/24    AS_PATH: [300, 200, 100]  ← 从 AS300 的视角

要到 192.0.2.0/24,先走 AS300,再走 AS200,最后到 AS100。

路径不是通过计算得出的,而是通过逐跳传播获得的。每个 AS 只是把自己知道的路径告诉邻居,邻居再告诉自己的邻居。

路径选择

面对多条可选路径时,AS 怎么选?两个核心因素。

LOCAL_PREF 是本地优先级,数值越高越优先,由本 AS 的管理员控制。AS_PATH 是路径经过的 AS 列表,越短通常越好,由传播过程自然形成。

BGP 选路的大致流程:

  1. 优先选择 LOCAL_PREF 更高的路径(策略优先)
  2. 如果 LOCAL_PREF 相同,倾向选择 AS_PATH 更短的路径
  3. 如果还相同,继续比较其他属性(MED、Router ID 等)

LOCAL_PREF 是本地策略,可以覆盖 AS_PATH 长度。

举个例子:

  • 路径 A:AS_PATH [200, 100],LOCAL_PREF 100
  • 路径 B:AS_PATH [300, 400, 100],LOCAL_PREF 200

虽然路径 A 更短(2 个 AS vs 3 个 AS),但 AS 会选择路径 B,因为它的 LOCAL_PREF 更高。

这就是为什么 BGP 不是最短路径协议。它优先满足的是商业策略,而不是数学上的最短距离。

路径追踪

逐跳映射

以哈工大教育网连接 Cloudflare DNS 为例。

nexttrace 2606:4700:4700::1111

输出:

1   2406:280:1003::/48     0.41 ms   AS24372  哈尔滨市
2   2406:280:1003::1       1.00 ms   AS24372  哈尔滨
3   2001:250:fe01:0:192:168:121:3  1.00 ms   AS4538   哈尔滨
4   2001:da8:ab:0:10::2    2.09 ms   AS24372  哈尔滨市
5   2001:da8:ab:0:202:118:170:42   2.92 ms   AS4538   哈尔滨市
6   2001:da8:257:0:101:4:8:400a    1.16 ms   AS4538   北京
7   2001:da8:2:119::1      2.31 ms   AS23910  哈尔滨市
8   2001:da8:2:2a::1       5.83 ms   AS23910  长春市
9   2001:da8:2:21::1      10.34 ms   AS23910  沈阳市
10  2001:da8:2:7::1       21.02 ms   AS23910  北京
11  2001:252:0:2::101     20.87 ms   AS23911  海淀区清华园李兆基科技大楼
12  2001:252:0:108::2     21.61 ms   AS23911  海淀区清华园李兆基科技大楼
14  2403:c780:b800:bb00:0:1:3335:1 166.79 ms   AS13335  香港
15  2400:cb00:582::/48     56.02 ms   AS13335  香港

跳 13 未响应。traceroute 中某些节点会丢弃 ICMP 探测包,这是正常现象。

哈工大(哈尔滨)→ 北京 → 哈尔滨 → 长春 → 沈阳 → 北京 → 清华园 → 香港。一条链路在华北和东北之间来回折返,这怎么看都不像最短路径。到底是谁在决定这些路径?顺着这个问题往下挖,就会发现互联网路由比找最短路径复杂得多。当然你也会发现上面的位置信息也不一定准确。

AS24372 和 AS4538 在哈尔滨本地有对等互联,流量在两者之间交换属于正常的本地汇聚拓扑,所以同一地理区域内会看到两个 AS 号来回切换。

逐段分析:

跳数ASRTT推断
1-2AS243720.41 / 1.00 ms哈工大校园网内部
3AS45381.00 ms进入教育网骨干
4-5AS24372 / AS45382.09 / 2.92 ms哈尔滨本地汇聚/交换
6AS45381.16 ms仍在本地。RTT 仅 1ms 出头,GeoIP 标北京存疑
7AS239102.31 ms切换至 CERNET2(教育网 IPv6 骨干)
8AS239105.83 ms比前跳增加约 3.5ms,约 300-400km 光纤距离
9AS2391010.34 ms比前跳增加约 4.5ms,约 400-500km
10AS2391021.02 ms比前跳增加约 10.7ms,最长的一段
11-12AS2391120.87 / 21.61 ms与跳10几乎持平,物理位置非常接近
14-15AS13335166.79 / 56.02 ms国际段,RTT 大幅跳变说明跨洋或 Anycast

跳7→跳8→跳9→跳10 的 RTT 增量(+3.5ms / +4.5ms / +10.7ms)与东北三省链路的城市间距大致吻合。跳11-12与跳10几乎持平,说明它们在同一区域。跳14的 166ms 跳升对应跨越了很长的物理距离。

注意:GeoIP 把跳6标为北京,但 RTT 仅 1.16ms 不支持这个结论。教育网 IPv6 地址的 GeoIP 精度本来就低,分析路径时 RTT 比 GeoIP 更可靠。

绕路原因

哈尔滨 → 北京 → 哈尔滨 → 长春 → 沈阳 → 北京,这段画圈路径的逻辑是:

  1. 跳 1-6 走的是哈工大校园网(AS24372)与教育网(AS4538)之间的本地互联,RTT 始终在 3ms 以内,说明流量一直在本地范围
  2. 跳 7-10 切换到了 CERNET2(AS23910),这是教育网专门的 IPv6 骨干网,拓扑独立。RTT 从 2ms 逐步增加到 21ms,符合东北链路的物理走向
  3. 两条骨干在北京区域汇聚后,送到清华园国际出口(AS23911)。跳11-12的 RTT 与跳10几乎持平,印证了这一点
  4. 最后在香港与 Cloudflare(AS13335)对接

这条路径由各 AS 内部骨干拓扑和商业关系决定。CERNET2 的 IPv6 骨干在东北地区就是按哈尔滨→长春→沈阳→北京铺设的,BGP 选路只能在这个拓扑基础上做选择。

教育网

教育网(CERNET)作为独立 AS,它的国际出口和三大运营商是分开的,而且有独立的 IPv6 骨干(CERNET2,AS23910)。这导致:

  • 教育网访问海外资源,通常需要先在国内绕到固定的国际出口节点(如清华园)
  • 教育网 IPv6 流量走 CERNET2 骨干,其拓扑和 IPv4 不完全重合,可能出现 IPv6 路径比 IPv4 更绕的情况
  • 不同运营商之间的互联点分布不同(北京、上海、广州),流量经常被导流到特定出口

这也是为什么有时候同一个海外网站,在学校(教育网)和家里(电信/联通)访问,路径差别很大,延迟差很多。

traceroute 里那些反直觉的现象

从哈尔滨到香港的路径要先在东北三省和北京之间来回折返,因为你的 ISP(教育网)和目的 ISP(Cloudflare)没有直接互联,流量必须沿着教育网内部的骨干拓扑走到指定的国际出口。

跳 14 的 RTT 突然跳到 166ms,跳 15 又回落到 56ms。延迟不是严格递增的,原因是回程路径可能和去程不同,或者遇到了 Anycast。Cloudflare 把同一个 IPv6 地址同时部署在多个地理位置,离你最近的节点会回复请求,所以不同跳的回复可能来自不同的物理位置。

同一个目的地,教育网、电信、联通走法差别很大,因为各 AS 的互联关系不同:教育网没有自己的广泛国际出口,必须集中到清华园等节点;运营商之间的 Peering 策略也不同。

traceroute 只能看到数据平面,也就是包实际走的路。路由器之间是怎么"商量"出这条路径的?这要看控制平面。

控制平面

MRT

MRT(Multi-Threaded Routing Toolkit)是一种数据格式,用于存储 BGP 路由表的快照。可以理解为互联网路由的原始录像。

一个 MRT 文件里包含某个时刻、某个 BGP 路由器上看到的全部路由条目:前缀、AS_PATH、LOCAL_PREF、MED、Community 等。

全球有很多公开项目提供 MRT 数据下载,比如 Route Views Project。但 MRT 是二进制格式,解析起来比较麻烦。

以刚才路径追踪中的跳 6 2001:da8:257:0:101:4:8:400a(CERNET 北京节点)为例,日常想查它的 AS 归属和路由路径,用在线工具更直接。whois 对 IPv4 比较有效,但查 IPv6 地址的 origin 字段往往没有结果。这里可以用 Hurricane Electric BGP Toolkit 进行查询。

Looking Glass

除了 Hurricane Electric,很多运营商自己也开了查询窗口,叫 Looking Glass。

原理一样:你向它的路由器发起查询,它返回自己路由表里到某个前缀的 BGP 路径。不同的是,HE 是一个聚合平台,Looking Glass 让你直接看到某个具体运营商的视角。

比如 Cogent Looking Glass。

输入一个 IP 或前缀,它会告诉你从这个 AS 的视角,到目标网段的最优路径是什么 AS_PATH、用了什么 Community。这和 traceroute 看到的数据平面是互补的。

数据平面 vs 控制平面

数据平面记录包实际走的路,控制平面记录路由器之间交换的路由信息。

nexttrace 看的是数据平面,记录的是包实际上怎么转发,包括 CERNET 和 CERNET2 骨干上的每一跳。BGP 和 MRT 看的是控制平面,记录的是路由器之间交换的路由信息,只关心 AS 级别的路径,不关心 AS 内部的具体跳数。

traceroute 的某条链路虽然物理上绕了远路,但 BGP 视角下可能只是一条很短的 AS_PATH。反过来,BGP 认为的最优路径,实际转发时也可能因为内部拓扑而被拆成很多跳。

总结

互联网由成千上万个 AS 拼接而成,BGP 负责在它们之间传播可达性信息。但路径选择不是由某个中心计算得出,而是每个 AS 根据本地策略独立决策的结果。

这意味着"最优路径"在 BGP 里是一个本地概念。商业关系、内部骨干拓扑、LOCAL_PREF 策略,这些因素的优先级都高于数学上的最短距离。再加上国内教育网独立、CERNET 与 CERNET2 分立、三大运营商各自为政的格局,同一条流量在不同网络里的走法差别很大。

所以下次看到 nexttrace 输出里那些绕来绕去的路径,不用觉得奇怪,那不是路由出错了,而是多方博弈后的正常结果。

参考链接