如果你已经追着《网络是怎样连接的》看到这一节,大概率已经接受了一个事实:网络包从你点击页面那一刻起,不是“嗖”一下就飞到了服务器,而是一站一站被转发的。前面几部分讲的是浏览器、协议栈、网卡、局域网交换机、ADSL/FTTH这些“家门口”的东西,到了4.5“跨越运营商的网络包”,画风突然就变了:你家的包被送进运营商网络之后,到底去了哪里?为什么没人能画出一张像样的“互联网地图”?这一节就是整本书里最接近“互联网本质”的部分之一,我会配合实际排查经验,把这节拆开细讲。
我准备这份精读版,不只是帮你把书里没明说的背景补上,还会顺带回答一个很多人卡住的问题:跨越运营商之后,网络包到底靠什么认路?丢包了又怎么看?这两件事其实是同一枚硬币的两面——理解了包在运营商网络间的转发逻辑,你自然就知道该在哪个环节找问题。
1. “4.5”在全书里的位置:从你家门口,走向别人家的网络
读精读版最忌讳的就是孤立地看某个小节。4.5之前,书里一直在处理“你”能控制的那一段:从浏览器按下回车,到封装出IP包、TCP段,再到把比特变成电信号送上网线,经过你家路由器和接入网设备,到达运营商设在路边的接入点。到这里,网络包其实才刚离开你的“势力范围”。
4.5之后的章节,注意力转向服务器那一端,开始讲数据中心、负载均衡、服务器如何处理请求。也就是说,4.5正好卡在整个通信链路的“中间地带”。这里是全书中读者最容易迷失的部分,因为它没有一个可以摸到、看到的设备。你家里至少有路由器、有网线,服务器机房好歹有实体机柜,但“运营商之间”只有一堆隐藏在机房角落里的路由器,和无数你看不见的光纤路由。
书里在这儿做了一个很关键的动作:把目光从“你接入的那家服务商”挪开,放到“服务商怎么互相连接”上。这个视角转变很反直觉——我们平时上网,总觉得互联网是一张统一的大网,可实际上它是由很多张“小网”拼起来的。运营商的骨干网就像高速公路网骨架,各家有各家的路,但光有路还不够,路和路之间必须有交叉口,4.5讲的就是这些交叉口和交规。
如果你是带着“我想知道我家的包走哪条路去服务器”这个问题读到这儿的,那这节就是答案的核心。
1.1 这一节真正解决的一个困惑
我自己初读这本书时,最大的困惑是:接入网已经把我送到运营商门口了,为什么还要花一整节讲“运营商网络”?难道运营商内部不就是一个大局域网吗?按这个思路想下去的读者,往往会觉得只要到了运营商骨干网,包就“自动”到达目的地,根本没有中间过程。
4.5要纠正的就是这个误解。运营商的骨干网不是一台巨大的交换机,它是由成千上万台路由器组成的网状结构。从你家接入点出发的包,先会被送到运营商本地的边缘路由器,然后一路经过汇聚路由器、核心路由器,在某个交界点交接到另一家运营商的网络里,最后才能进入目标服务器的局域网。
这个过程里,每一跳都可能因为路径选择、带宽拥堵、设备故障产生延迟和丢包。所以“跨越运营商”这件事,本质上就是“在一群互不隶属的网络之间接力投递”。搞明白这一点,你后面看BGP、看IXP、看丢包率,才有落脚的坐标系。
2. 先把“运营商”这三个字拆干净
中文语境里,“运营商”第一反应总是电信运营商这类大公司。但在网络原理层面,4.5里说的“运营商”更接近一个泛称:凡是运营一张独立网络、有自己的路由策略、能和别人对等连接的实体,都可以被称为运营商。一个大学、一家云厂商、一个跨国IDC,只要它有自己的自治网络,在互联网体系里说话的地位和所谓运营商是一样的。
这个概念必须反复强调,因为后面所有技术名词,比如AS(自治系统)、BGP(边界网关协议),都建立在“网络是由多个独立王国组成”这个前提上。每个王国自己管内部的路由,王国之间靠专门的协议谈外交。
2.1 接入网、区域网、骨干网,别混为一谈
书里把运营商网络分成几层:离你最近的接入网,负责把你家光纤小区宽带汇聚上来;再往上是有一定区域范围的城域网/区域网;最上面才是跨地区、跨国家的骨干网。这三层网络不是三张独立的网,而是从边缘到核心的递进关系。
你的包先走过接入网,到达运营商的接入点(POP,Point of Presence)。POP可以理解成运营商在一个城市或区域的“办事处”,所有用户的流量在这里被汇总,然后再向更核心的节点转发。核心节点之间用高速骨干链路互联,节点和节点之间的连接方式通常是网状或者准网状,这样即使某一条光纤断了,也还有别的路可以绕。
4.5其实默认你已经理解了这些层次,所以它真正想讲的是:当流量在你所在运营商的骨干网上走到一个“边界”时,如果目的地不在自己网络里,它就得找一条路跨出去。跨到哪里?跨到另一个运营商的地盘。这个“跨出去”的动作,就是全节的重点。
2.2 一个包到底什么时候算“跨越运营商”
很多人把“跨越运营商”想象成从电信网络跳到联通网络这种肉眼可见的切换,但实际上,这个判断标准很简单:只要包从一个自治系统进入了另一个自治系统,就算跨越了运营商。哪怕两个运营商在同一个机房交换数据,物理距离只有几米,这也是一次AS之间的跨越。
反过来,如果包从北京用户出发,经过自家骨干网到上海,再绕回北京,只要没跳出自己所在的AS,它始终只是在“同一个运营商内部”转,不叫跨越运营商。这个区分直接影响BGP路由的决策,后面我会讲到。
我自己做链路排查时遇到过这种情况:用户投诉访问某服务很慢,拿traceroute一看,所有跳数IP看起来都很正常,最后发现包在一个AS内部绕了七八个节点。这就是典型的路由策略问题,不是设备坏了,而是这家运营商内部的路由选择不合理。能把AS边界看清楚,这类问题至少能排查一半。
3. 跨越运营商网络后,包靠什么“认路”
走到这,可以进入技术细节了。在局域网里,包是靠MAC地址和交换机的转发表找到下一个端口的,但出了接入网,这一套就彻底失效。运营商网络里的路由器数量多到无法用广播去发现彼此,也不可能靠MAC地址做全局寻址,所以从这开始,IP地址和路由表成为唯一的认路依据。
3.1 路由器转发的三件套:查表、改IP头、换链路层帧
一个网络包在运营商路由器上经过,至少会发生三件事。第一,路由器解封装收到数据帧,取出里面的IP包,用目的IP地址查路由表,按最长前缀匹配原则选出一条最佳路由,确定下一跳是谁。第二,路由器把IP头里的TTL值减1,如果TTL变成0,这个包就会被丢弃,同时发回一封ICMP超时消息。第三,路由器根据下一跳的IP地址,通过ARP协议找到对应MAC地址,重新封装成新的数据帧,从正确的物理接口发出去。
这三件事看起来简单,却是整个运营商网络转发的基础。每过一台路由器,包的IP地址不变,但MAC地址永远在变。MAC地址只负责“这一段链路”的交付,IP地址才负责“端到端”的寻址。4.5里强调的就是这种“接力棒”式的交付逻辑。
3.2 为什么路由表不是一张“世界地图”
理想情况下,如果每台路由器都知道全互联网的路由,路径选择肯定最优。但实际上,全互联网的IP前缀数量早就超过了数十万条,别说全网同步,单是存储和处理全球BGP路由,对设备性能就是不小的考验。更现实的做法是分层路由:核心路由器负责维护全球路由细节,边缘路由器只需要知道“外界的默认方向”就行。
书里提到的“默认路由”概念特别值得多说一句。对于接入网层级的设备来说,维护一张完整互联网路由表是浪费的,它们往往配置一条默认路由,把所有不知道往哪去的流量一股脑送给上游。这个设计看着粗糙,却非常实用,就像是小城市的快递站,它不需要知道全国所有街道的详细路线,只把包裹交给省转运中心就行。
这个机制直接解释了为什么你家路由器里的路由表那么小,却也能上网。它不需要认识全球网络,只需要知道“把包交给运营商”就够了,真正复杂的路由决策,都发生在运营商骨干网络的高层设备上。
4. 运营商之间的“外交规则”:自治系统和BGP
讲清楚了单台路由器的转发逻辑,下一步就是更难的问题:两个运营商之间的路由器凭什么愿意把对方的包接过来,又凭什么愿意把自己的网络信息告诉对方?这时候就要引入自治系统的概念。
4.1 自治系统(AS)到底是个啥
简单说,自治系统就是一组由同一个机构管理、执行相同路由策略的路由器和网络组成的整体。每个AS都有一个全球唯一的编号,叫ASN(AS Number)。有了这个编号,互联网上不同的网络之间就有了“户口”,彼此也能用编号精确地说“我指的是哪个系统”。
这里有个很漂亮的抽象:无论一个AS内部部署了多少台路由器,也无论它用OSPF还是IS-IS,或者干脆用静态路由,对外界来说,它都只是一个“点”。运营商之间不需要关心对方内部怎么折腾,只需要知道怎么把这个AS的数据交给另一个AS。
这正是BGP存在的价值。BGP,全称边界网关协议,是AS与AS之间交换路由信息的唯一标准协议。BGP运行在TCP之上,说白了就是两台路由器建立一条TCP连接,然后通过这条连接来互发路由信息。
4.2 BGP在交换什么:路由通告
BGP交换的消息核心是“路由通告”。一条通告大致包含三块信息:IP前缀(我这边能到达哪个网段)、AS路径(要经过哪些自治系统才能到达这个前缀)、以及一堆路径属性(这条路由的优先级、来源等信息)。
举个例子,假设我的网络里有一个网段203.0.113.0/24,我想让隔壁运营商也能访问这个网段,我就会通过BGP告诉它:从我这个AS可以到达203.0.113.0/24,AS路径是65001。隔壁运营商把这条通告收下,放进自己的BGP路由表,如果它决定采用,再继续向它的邻居通告时,就会把AS路径改成65001 65002。这样一层层传下去,全世界都知道了去这个网段的路。
这就是为什么BGP被称为“路径向量协议”——它不只是告诉你目的地怎么走,而是把整条路径上经过的AS都列给你看。这给网络管理员一个重要的判断依据:路径越短的通常性能越好,但也不绝对,有时路径长的反而延迟更低,因为链路的物理质量差异很大。
4.3 IXP:让天南海北的运营商“同处一室”
BGP解决了“怎么交换路由”的问题,但还没有解决“物理上怎么连”的问题。早年运营商之间互联,要么直接拉一条专线对接,要么在一个中心节点上层层转接。专线成本高,转接又增加跳数。于是就有了IXP,互联网交换中心。
IXP可以理解成一个中立的机房,里面放着高性能的交换机。众多运营商的BGP路由器都把自己的设备拉进这个机房,接到同一台或多台交换设备上,然后两两之间建立BGP会话。这样一来,本来要跨越大半个城市才能碰面的两台路由器,现在物理上只有几米远,互联成本和延迟都大大降低。
书中4.5虽然没有把IXP当作重点铺开来讲,但它提到运营商之间要绕到专线或者经由中转结构,这背后的实指就是IXP和BGP的配合。现代互联网能维持相对较低的延迟,IXP功不可没。可以这么说:没有IXP,就没有今天“任意两个网络都能低成本互访”的便利。
4.4 BGP选路时的几个“潜规则”
BGP选路不是简单找最短路径,而是有一整套优先级排序规则,最常见的包括:本地优先级越高越优先、AS路径越短越优先、MED值越小越优先、EBGP路由优先于IBGP路由。这些规则的目的,是让每个运营商都能根据自己的商业策略和网络质量做灵活控制。
实际操作中,国内很多网络管理员对BGP一知半解,只知道“配一条对等就行”。真要出问题时,最头疼的就是BGP路由被错误通告,或者邻居运营商把路由策略设得很偏,导致流量绕远。这些都属于“跨越运营商”环节的经典故障,可惜书里篇幅有限,只讲了原理。如果你读完4.5有想深入研究的冲动,BGP选路规则绝对是下一个值得啃的硬骨头。
5. 跨越运营商后,丢包怎么看才靠谱
这一节之所以特别值得展开,是因为很多人在自己家里ping不通某个IP时,第一反应就是抱怨运营商,但看了4.5之后你应该知道:一个包从你家到目标服务器,中间可能要跨好几个AS,其中任何一段出问题都可能导致丢包。那么问题来了,到底是哪一段出了问题?这就必须学会看丢包率。
5.1 丢包率不等于延迟,别混为一谈
先纠正一个常见误区:丢包率和延迟是两回事。延迟高,说明包虽然能送到,但路上耗了很久;丢包率高,说明有相当一部分包根本没送到目的地。TCP协议遇到丢包会自动重传,TCP层的重传会进一步增加整体延迟,所以你看到的高延迟有时候只是丢包的次生灾害。
丢包率的本质很简单:发出的包数量减去收到的包数量,再除以发出的包数量。但在实际网络环境里,测量手段决定了这个数字有多大参考价值。最常用的测量工具是ping,它靠ICMP回显请求和回显应答工作,但注意,ICMP包的转发优先级通常低于正常业务流量,甚至有设备还会人为丢弃ICMP。所以ping出来的丢包率,并不完全等于真实业务流量的丢包率。
5.2 用ping做基础丢包测量
最标准的做法是发一批连续的ICMP包,然后看统计结果。以Linux为例:
ping -c 20 -i 1 目标IP-c 20表示发送20个包,-i 1表示每个包间隔1秒。命令结束后的汇总输出里,你会看到“20 packets transmitted, 18 received, 2 lost, 10% packet loss”这样一行。这个10%,就是这段链路的ICMP丢包率。
这里有几个判断参考值:局域网内丢包率应该为0,运营商的骨干网优秀线路丢包率小于1%,跨运营商线路丢包率超过5%就要引起注意,超过10%基本可以判定为严重链路问题。当然,这个标准不是绝对,高负载骨干链路或者小运营商线路更容易波动。
5.3 用traceroute看丢包到底发生在哪一跳
ping只能告诉你链路的整体结果好不好,但无法告诉你差在哪一段。这时要用traceroute(Windows上叫tracert)。它的工作原理是利用TTL:先把TTL设成1发出去,第一台路由器收到后减到0就会丢弃并回应ICMP超时消息,这样就得到了第一跳;然后TTL设成2,得到第二跳;依次类推直到到达目的地。
traceroute最直观的输出是每一跳的IP和延迟,如果某一跳显示星号(*),通常说明这一跳没有回应。这里面有个特别重要的坑:星号不等于丢包。很多路由器出于安全或者性能考虑,主动不回应ICMP超时消息,但它们对转发的数据包是完全正常的。所以看到个别星号不要太紧张,更靠谱的做法是看整条链路里,星号是不是连续出现,以及最终目标的丢包率是否过高。
除了星号,你还要关注延迟的“跳变”。比如前几跳延迟都在10毫秒左右,突然某一跳变成50毫秒,后面所有跳都稳定在50毫秒附近,那么这个跨越点很可能是运营商之间的边界,也可能是跨地区的骨干链路。这个“突然抬高”的跳跃点,往往就是丢包和延迟问题的高发区。
5.4 用MTR做连续观测,揪出隐藏的丢包
traceroute只能反映某一瞬间的状态,网络链路是会波动的,尤其运营商之间的互联线路,经常出现时段性拥塞。这时候就要用到MTR,这个工具把ping和traceroute结合到一起:它对每一跳都持续发送一批包,实时统计每一跳的丢包率和延迟,并持续刷新。
Linux下可以直接安装mtr包,常用用法:
mtr -rw -c 60 目标IP-r表示生成报告模式,-w是宽格式输出,-c 60表示每跳发送60个包。输出表格里会很清楚地显示每一跳的Loss%和延迟。实际操作中,我会特别关注两列数据:目标IP的Loss%和各中间节点的Loss%。如果中间节点丢包很高,但目标节点丢包很低,那大概率是中间节点对ICMP做限速,不一定是真的丢包;如果某一跳之后的所有后续节点丢包率都很高,那问题就出在这附近。
这种逐跳判断的方法,做跨运营商网络排查时格外有价值。因为不同运营商之间的BGP路径选择、链路质量和路由策略差异很大,不逐跳看,很难定位责任方。
5.5 丢包排查的几个实用心法
第一,多测几次再下结论。一次ping的丢包率可能只是瞬时抖动,一定要在早晚高峰、低谷各测几次,综合看趋势。跨运营商链路的丢包往往有明显的时段性,比如晚高峰冲刺、凌晨恢复,这种规律一旦摸清,问题原因就基本清楚了。
第二,用大包和UDP协议交叉验证。有些网络对ICMP小包很宽容,但对TCP/UDP大数据包很敏感。可以试着用ping -s 1400发送接近MTU的大包,看是否出现丢包或分片问题。也能用专门的TCP/UDP测速工具做双向吞吐测试,这往往比ICMP更能反映真实业务体验。
第三,分清哪端该负责。同一个丢包现象,可能根子在本地接入网、可能在跨运营商互联点,也可能在目标服务器的机房。最实用的思路是:先用ping测目标IP,再用traceroute定位中断跳段,最后用MTR持续观察。三步走完,整个链条的责任归属基本就水落石出了。
6. 精读到这,我自己的排障思路被重构了
读完4.5之后,最大的变化是:我再也不把“跨运营商”当成一个模糊的形容词。以前做网络排障,看到用户反馈卡顿,第一反应是重启路由器或者换DNS,现在我会在脑子里自动把整条链路切成几段——客户端到接入网、接入网到运营商边缘、运营商核心之间、跨AS交界点、目标侧机房。这种分段思考,就是从“跨越运营商的网络包”这一节里学到的。
而且这一节让我意识到,互联网的稳定不是靠某一家公司特别强,靠的是各家自治系统愿意按BGP的规则互通有无。当你看到一个包在运营商之间顺利穿越时,你看到的其实不是一个技术动作,而是一整套由AS号、路由通告、IXP共同构成的社会契约。技术书上白纸黑字写的BGP、IXP,放到真实互联网里,就是每天数亿次握手的基础设施。
如果你正在跟读这本书,我建议不要急着往后翻,先把这一节提到的路线图在脑海里重建一遍:包离开你家路由器,进入运营商接入点,穿越骨干网,到达AS边界,通过BGP与IXP完成交接,再一路下行到目标服务器。每多走一步理解,你对“网络卡了”这件事的判断都更准确一层。等哪天你碰到跨运营商丢包的问题,能用上我前面说的traceroute和MTR那套流程,你大概就会认同我现在的体会:这一节才是整本书最被低估的“内功心法”。