资讯动态

BGP选路机制详解:从属性博弈到网络排障实战

发布时间:2026/10/20 11:56:51 来源:尧图企业网站定制
BGP全称是Border Gateway Protocol边界网关协议。我最早接触它的时候是被那句“BGP是互联网的粘合剂”给唬住了觉得这是只有运营商和顶级网络专家才需要碰的东西。直到后来自己动手搭实验环境、处理真实网络故障才慢慢意识到BGP其实没那么玄乎它本质上就是一套“如何从一堆可达路径里挑一条最好的路”的规则体系。今天这篇东西我不打算从头讲到尾把RFC翻一遍也不打算把默认优先级表格丢给你就完事。我想换个角度从“选路到底是怎么发生的”这个核心问题切入把属性之间的博弈、优先级背后的逻辑、以及实际维护中那些文档上写不清的坑都揉碎了讲清楚。不管你是刚接触网络的新人还是在职场上被BGP路由折腾过的工程师这篇文章应该都能给你一些不一样的启发。1. BGP选路不是“选快”而是“选优”先搞懂它的决策本质很多人容易陷入一个误区觉得BGP选路既然是“选路”那肯定是哪条路延迟低、带宽大就走哪条。这种想法放到IGP比如OSPF、IS-IS里大体成立因为IGP看的确实是带宽、时延、开销这些物理或者逻辑上的“成本”。但BGP根本不管这套它跑在自治系统之间面对的是成千上万个AS它关心的核心问题只有一个这条路径能不能到达目的前缀以及这条路是不是最符合策略的那一条。1.1 为什么BGP倾向于“不换路”BGP选路的一个底层逻辑是抑制震荡。想象一下全球互联网有多少条路由在持续更新如果每条路由都因为带宽抖动频繁切换那整个世界都会跟着抖起来。所以BGP的设计哲学是只要还有一条可达的旧路由就不要轻易切换到新路由哪怕新的看起来“更好”。这正是为什么BGP选路规则里第一条可用的最优候选路由会一直保持直到它彻底失效而不是像IGP那样周期性重新计算。这一点很多人学BGP时容易忽略。我们总是盯着那十几条选路规则看却忘了这套规则是搭在“稳定性优先”的地基上的。明白了这个底层逻辑你才能理解后面所有属性的意义——它们不是用来帮你找“最快路径”的而是用来帮你找“最符合策略”的路径的。1.2 决策过程是单线程的“淘汰赛”实际选路不是把所有路径拿过来做综合评分然后取总分第一。BGP的决策过程是一套顺序执行的淘汰赛从第一条规则开始拿所有候选路径比一轮如果有且只有一条胜出那直接选它后面所有规则统统不执行如果还有多条打平再进入下一条规则直到最后只剩下一条。这个机制很重要因为它意味着第一条属性的“情绪稳定”和“取向偏好”会直接影响后面所有规则的“出场机会”。举个最简单的例子如果某条路由的Weight权重特别高那么在权重比较这一关它就直接胜出了后面什么AS路径长度、LOCAL_PREF压根没有机会参与比较。所以我们在维护路由时经常说“想要控制选路就要尽量在靠前的属性上做文章这样效率最高也最好排查”。1.3 选路规则里的“先手优势”我把完整的决策顺序放在这里后面会逐条拆解。你可以把它当作一张速查卡Weight权重最高者优先Cisco私有属性本地有效LOCAL_PREF本地优先级最高者优先本地始发路由network / aggregate / redistribute优先于从对等体学习到的路由AS_PATH长度最短者优先ORIGIN类型IGP EGP INCOMPLETEMED多出口鉴别器最小者优先外部路由EBGP优先于内部路由IBGP经过的IGP邻居的下一跳度量最小者优先会话建立时间较早者优先老路由更稳Router-ID最小者优先对等体地址最小者优先这套顺序十个人有十一个能背错但实际工程里最重要的是前六条后面几条大多是拓扑完全相同、没有其他区分手段时的“兜底方案”。你只要把前六条的逻辑吃透就已经能解决90%以上的选路问题了。2. 从Weight到AS_PATH手把手拆解“先到先得”的四大关键属性这一节我打算不按表格顺序平铺而是按实战中“由近到远”的视角来拆先从本设备自己能控制的属性讲起再到从邻居学到的属性这样你会有一种“层层递进、每一步都能操作”的感觉。2.1 Weight只属于本设备的“独裁者”Weight是Cisco实现里的私有属性它在本地路由器上生效不会传递给任何邻居。你可以把它理解成“这台路由器自己内心的一票否决权”数值越大越优默认值是0本地宣告的直连路由权重通常是32768。这玩意儿的最大特点就是范围极小、控制力极强。在实操里我经常用Weight来做一些“只影响本机出方向”的临时调整。比如某天一条出口链路抖动运营商那边的BGP路由变了但我想让本设备暂时多走另一条备份链路又不想动上游策略那直接在入方向的路由策略里set weight 55555问题就解决了。因为Weight只对本地有效其他邻居、其他路由器完全感知不到所以特别适合做故障期的“快速止血”不会造成全网路由震荡。但也有个坑Weight无法跨设备传递也无从在show output里直观比较。如果你在多台设备上都设了Weight一定要保证策略一致否则很容易出现“这台设备往左走那台设备往右走”的分裂路径现象。在排查这种问题时我会第一句问的就是“你们在哪些设备的入方向set了weight”2.2 LOCAL_PREF自治系统内部的“共识决议”如果说Weight是“个人的执念”那LOCAL_PREF就是“一个自治系统内部的共识”。它是IBGP邻居之间传递的属性默认值为100也是“越大越优”。它的核心价值在于当你的AS有多个出口点连了多个运营商/多个上游时你想要全AS的出方向流量都优先走某一个出口就可以通过LOCAL_PREF来实现。我讲一个实际案例很多做企业网络的同事应该都有共鸣双线接入一条是电信一条是联通我们希望在正常情况下所有出方向流量都走电信只有电信挂了才走联通。这个需求用LOCAL_PREF就非常优雅在电信侧设备上对从电信收到的路由设置LOCAL_PREF为150联通侧保持默认100。因为LOCAL_PREF会在IBGP全网传递所以AS内所有路由器都会计算出“去往任意前缀的最优路径是电信那条”就把流量优先引过去了。当电信链路断了该前缀从BGP表中消失联通那条自然成为备选流量自动切换。这里有个细节值得注意LOCAL_PREF只在AS内部传递不会带着出AS。也就是说你给上游运营商下发的路由加LOCAL_PREF对上游没有任何影响——它的作用范围是“接收方自己所在的AS”。2.3 AS_PATH长度跨AS决策的“硬通货”这条规则可能是大家最先记住的AS路径越短越优。为什么会这样设计因为AS_PATH本身记录了这条路由穿越的自治系统集合路径越短意味着对端AS越“近”跨域跳数越少通常也意味着更稳定、更少的中转。对运营商网络来说AS_PATH长度往往被当作一种“路由成本”的近似值。但这个规则在实践中经常被“恶意”利用。最典型的就是AS_PATH Prepending人为地在路由上重复添加自己的AS号把路径“变长”从而让下游邻居“看不起”这条路由于是他们就更倾向走另一条更短的路径。这几乎是所有双线/多线接入场景里控制入方向流量的标准姿势。我做过多线接入优化时就经常给备份链路的出方向策略里prepend两三次自己的AS号让对端运营商感觉“这条路绕了远路”从而把入方向流量尽量压制在主链路上。实测下来一般在备份链路上prepend 2到3次比较合适——太少了不管用太多了万一主链路全挂备份链路撑不住全量流量就悲剧了。2.4 AS_PATH在选路中的另一个身份防环和策略工具除了选路AS_PATH还有一个专长防环。BGP明确规定如果一条路由的AS_PATH里包含了自己的AS号那它就收到了一条“在AS内绕了一圈又回来”的路由这种情况必须直接丢弃。这就是BGP最重要的防环机制它根本不需要额外配置天然自洽。在实际维护中AS_PATH也经常被用来做“路径过滤”。比如我们跟某些不靠谱的下游有互联为了防止他们一不小心成了我们所有流量的中转我们可以用AS_PATH ACL精确匹配、只允许特定AS_PATH通过。这种打法比用前缀过滤器更精细也更难被绕过。我习惯在做安全排障的时候同时挂上前缀过滤和AS_PATH过滤两道关卡宁可过度防护也不给路由泄露留机会。3. 谁是“最轻”的那一个ORIGIN、MED与下一跳的隐秘权重很多人学到前四条就以为差不多了但真实故障往往就藏在后面几条“不太起眼”的属性里。ORIGIN、MED、IGP下一跳度量这三兄弟在多数情况下打前四条打平了才登场但一旦登场往往决定了流量方向的天平往哪边倾斜。3.1 ORIGIN路由出生地的“血统”标记ORIGIN属性用来表示这条路由是怎么进入到BGP世界的有三种取值IGP通过network宣告最可信值2、EGP外部网关协议已基本绝迹、INCOMPLETE通过重分布等途径进入可信度最低值1。它的优先级是IGP EGP INCOMPLETE也就是说它是“越小越优”数值上2优于1但因为EGP实际几乎不出现所以核心就是IGP优于INCOMPLETE。实战中你直接配置ORIGIN的机会不多但它经常在“暴力重分布”的场合里冒出来搞事。比如有人把OSPF整个重分布进BGP那产生的路由ORIGIN就是INCOMPLETE血统最低。如果同一个前缀同时存在network宣告和重分布两种来源即使后者的AS_PATH更短BGP也会因为ORIGIN优先级更高而选择那个“血统更纯”的network路由。这很容易让人困惑路径短为啥不走原因就在这儿——血统很重要出生决定命运。3.2 MED跨AS的“价格标签”与它的边界限制MED全称Multi-Exit Discriminator多出口鉴别器它是唯一一个正经用来“跨AS”传递并影响对端AS选路的属性但它有个硬约束MED只能传递给相邻的AS不会继续往更远的地方传。机制上前置条件是默认值0越小越优。它的应用场景很典型两个AS之间有两条物理链路互联AS1希望AS2去往某前缀时优先走其中一条链路。那AS1就可以在自己的两条出口上对播出的该前缀设置不同的MED值比如主链路MED50备份链路MED200AS2收到后会自动优选MED更小的那一条。用大白话讲就是给两条路贴了不同的“价格标签”对端就会自动选“便宜”的那条。但MED有个比较坑的地方它的比较是有限制的。BGP默认MED比较只发生在“源自同一个AS的两条路由”之间也就是需要参数bgp always-compare-med来打破这个限制否则不同AS来源的路由之间不做MED比较。我曾经在排障时看到两个上游给同一个前缀发了不同的MED但路由器始终不走MED更小的那条结果一查才发现它们来自不同的AS默认根本不会触发MED比较。这个参数官方文档写得零散但实际运维里极其关键。3.3 下一跳IGP度量的“战术价值”最终路径优化到了这个阶段BGP已经选出了“外部视角最优”的路由但如果它要真正把流量发出去还需要知道下一跳在自己的IGP路由表里有多“好”。所以第8条规则就登场了比较到达BGP下一跳地址的IGP度量值越小越优。这条规则的存在是BGP和底层IGP之间恰到好处的一种“协同”。因为BGP自己不看物理拓扑细节它依赖IGP来告诉它“怎么走最划算”。如果两条BGP路由下一跳不同但其他所有属性全打平那IGP度量小的一方就会胜出。尤其是在一个复杂的IBGP体系里这个规则经常在“多台Route Reflector指向不同物理出口”的场景下发挥真实作用。经验上我通常不会主动去调IGP度量来影响BGP选路——太绕了而且很容易把IGP内部的链路开销搞得异常。但我会在排查选路异常时先顺手看一下这两条路由的下一跳在IGP里的度量值。有两次我排了半天都没找到问题最后就是这一关“兜底”才把真正的差值揪出来。4. 我们在真实网络里是怎么“摆弄”这些属性的四类调控手法前两节我们拆了属性这节我想重点落地既然知道了BGP按顺序比属性那实际维护中我们是怎么用工具达到“我要它走这条它就得走这条”的这四类手法是我在工作中最常用的建议你收藏。4.1 入方向工具控制“别人怎么看待你的路由”所谓入方向是指“其他AS往你的AS发送流量时会选择哪条路”。由于路由是你宣告出去的对你自己的BGP路由做属性修改只影响别人对你AS内的路径偏好。常见操作AS_PATH Prepending把备份链路宣告的路由人为拉长让上游觉得这条路绕远从而减少入流量MED设置在给不同上游的出口上设置不同的MED引导对端优先走指定链路前缀精确宣告用更精确的前缀比如/24而不是/16在主链路宣告让更细粒度的最优路由自然出现这套手法里的AS_PATH Prepending通常会配合ip as-path access-list或者route-policy一起用。比如我最近维护的一个双线出口就做了这样的配置示意route-policy PREPEND permit node 10 if-match ip-prefix important-prefix apply as-path prepend 65001 65001 65001 apply med 500 end-policy # 上面这个策略仅在备份链路方向生效 # 主链路方向不做任何修改靠自然属性胜出。这样设完之后我用show ip bgp 8.8.8.0/24一查非常直观主链路AS_PATH长度短备份链路AS_PATH长度被拉长了入方向流量自然集中到主链路。要测试效果的话可以在维护窗口手动把主链路的物理接口shutdown观察备份链路是否能承接流量再恢复。4.2 出方向工具控制“你的流量怎么走出去”出方向是指“你的AS访问外部目标时优先走哪条出口”。这完全由你本地及AS内部的策略决定。核心工具就是Weight和LOCAL_PREF。只影响某一台本地设备使用Weight影响整个AS使用LOCAL_PREF并通过IBGP全量传递我早年在维护双出口时刚开始不懂LOCAL_PREF的“网内共振”特性只在出口路由器A上设置了路由策略结果别的主机访问外网还是走的旧路径。后来才明白LOCAL_PREF必须靠IBGP在整个AS内同步才能让全AS的路由器达成共识。于是我把策略改到出口设备的入方向并确认IBGP邻居关系正常建立再一查show ip bgp所有路由器都认了这条LOCAL_PREF200的路由出方向流量才顺利切过去。4.3 出/入方向的组合拳多技术出口的最优路径矩阵当你的AS有多个出口、多条链路、多个运营商时单独靠任何一个属性都不完美。我们通常会用“组合拳”来构建一张最优路径矩阵。假设企业在两个城市各有一个机房分别连接两个不同的运营商且通过专线/Overlay组了IBGP全网。我们需要实现南方用户走南方出口、北方用户走北方出口、附近机房互备。这种场景我会把LOCAL_PREF和AS_PATH Prepend搭配起来玩南出口设备上对南方运营商的线路宣告全国前缀AS_PATH不修饰LOCAL_PREF默认或稍高北出口设备上对同一前缀宣告时AS_PATH prependLOCAL_PREF低一些这样外部流量从南方进来找不到更优路径逆向往北走内部流量出境则优先走本地区域两边形成流量平衡这种矩阵设计不是一次配置完就一劳永逸的而是要持续观察流量曲线、对端路由表反馈来微调参数。做网络优化的人本质上就是在这些属性参数里“弹钢琴”。4.4 策略下发前的“小动作”过滤与抑制先堵后梳在实际操作中我很少只单纯改属性而是一上来先做“过滤抑制”的预处理入方向挂前缀列表、AS路径过滤器把不想要的、不该收的路由直接挡在门外出方向只宣告我们真正持有的、合法的前缀防止路由泄露或恶意路由广播针对震荡路由使用bgp dampening抑制半衰期高的路由防止“一会儿通一会儿断”影响全局为什么要先做这一步因为属性调控是基于“已有路由”的如果有大量垃圾路由混进来那即使LOCAL_PREF调得再优也只是在垃圾堆里挑“相对好的垃圾”完全没意义。把不健康的路径先剔掉剩下那些可比较的路径才有应用选路策略的价值。5. 那些年我们踩过的选路坑真实排障案例与思维复盘讲完理论和方法不聊几个真实踩坑案例总觉得少了点灵魂。下面这三个案例都是我在维护不同类型的BGP网络时实际碰到的问题都很典型希望你能从中看到自己网络的影子。5.1 案例一LOCAL_PREF“传不出AS”引发的双向流量失衡某次做跨城双线优化我按老经验在主出口上对某段重要前缀设置了LOCAL_PREF180备份链路默认100。配置完成后同城数据中心内部访问外网的情况正常但我顺手检查了一下上游的入方向流量发现几乎全是走备份链路进来的与我预期的“主链路优先”完全相反。当时我第一反应是主链路宣告出了问题查了附属的所有节点发现宣告正常MED默认0。后来才回过神来LOCAL_PREF作为IBGP属性它只在AS内部传播我设置的180只对内部路由有效对上游AS没有任何意义。上游AS判断“走哪条路进入我的AS”取决于我宣告给它的AS_PATH和MED而不是我本地LOCAL_PREF的数值。这个案例给我们的教训是方向对应关系必须时刻记清——控制“出”靠Weight和LOCAL_PREF控制“入”靠AS_PATH Prepending和MED。方向搞反跑断腿都查不出问题。5.2 案例二MED比较的“非对称陷阱”在双归接入时突然出现某金融客户做双归接入两条链路分别接两个不同的运营商上游各自宣告了相同的网段。我们原本预期去往某些地址时因为运营商B的MED较小流量会优先走B链路。但实测中发现流量几乎总走A链路怎么都切不过去。排查链路层层递进首先排除物理、接口、BGP会话问题再用show ip bgp对比两条路由的完整属性发现它们的AS_PATH长度、LOCAL_PREF都完全一致只有MED不同理论上应该走MED更小的B链路。问题来了为什么没走后来我才想起来这个场景下两条路由是来自两个不同AS的。BGP默认规则是只有同一AS来源的路由才做MED比较不同AS来源直接跳过MED比较进入后面“教条式”的规则比拼。也就是说MED想跨不同AS比较必须在设备上全局开启bgp always-compare-med。在这个真实切换案例里这参数开不开直接决定了流量是否按预期流动。5.3 案例三AS_PATH短不一定绝对优先ORIGIN血统一击绝杀某次做路由优化我们想让一部分流量从更短AS_PATH的主链路走。按常规理解AS_PATH最短一定会胜出。可是配置完成后我们用工具追踪路由路径流量却仍绕道备份链路主链路上的AS_PATH虽然短但就是没被选中。用show ip bgp prefix细看属性发现主链路那条路由的ORIGIN是INCOMPLETE备份链路那条是IGP。回头再对照决策规则的顺序AS_PATH比较(规则4)排在ORIGIN之前所以只要AS_PATH有长短差异理应立刻生效。但这个案例中两条AS_PATH长度其实一样它们打平后进入ORIGIN比较于是血统更正的IGP反而胜出。后来我们用network命令显式宣告这个前缀让ORIGIN变成IGP再对照show ip bgp一看选路立刻切到了主链路。这个案例说明决定选路的永远是决策顺序里最先出现差异的那一条属性。不是哪个“显眼”就哪个说了算而是“先比谁”才说了算。理清属性顺序你才能预判结果。6. 属性跟踪与调试指南日常维护里我用得最顺手的几条命令网上有很多BGP的show命令大全但真正日常维护用得最频繁的其实就那几条。我在这里把它们串成一个完整的排障链路让你遇到选路异常时能一条龙排查。6.1 show ip bgp不是只盯着BGP table还要学会“逐行理解”show ip bgp是基础但我强烈建议你多看一眼Network Next Hop Metric LocPrf Weight Path这一行里的每个字段。尤其是当你的前缀有多种来源时你会看到同一个Network下面挂着多行不同Next Hop的路径每一行都对应一条“候选路径”。通过它的输出我们能定位到“具体打平到了哪一步”如果某行有标记说明它是当前最优路径顺着它的属性回溯就能知道它到底赢在哪一条规则上。如果某些行完全相同的属性一长串那大概率后面几条“兜底规则”在起作用这时也要警惕“该加参数区分路径了”。6.2 show ip bgp rib-failure一个被严重低估的调试入口很多人在BGP选路不理想时只盯BGP表却忽略了show ip bgp rib-failure这个命令。它专门用来展示那些BGP认为是最优路径、但为什么没有装进路由表RIB的记录。出现RIB failure通常意味着路由冲突比如去往同一前缀有其他协议如静态路由、OSPF的路径在路由表里占据了优先级BGP就算选出来也放不进去。这是一个特别容易让人抓狂的坑你查BGP表明明有一条最优路径策略也都对但流量就是不过去。结果一看RIB failure才发现底层路由表被一条静态路由霸占了。所以每次选路排查我都会先跑一遍show ip bgp rib-failure五秒定位是否有“BGP赢了属性却输了安装权”的诡异局面。6.3 show bgp neighbor和debug ip bgp updates观测邻居的“心情状态”最后是邻居层面的排查。BGP选路的前提是邻居关系稳定。show bgp neighbors是基础但我更常用它来看“发过来/收过去”的更新统计确认当前更新的内容与预期一致。遇到选路突然变化并伴随便更新再考虑抓包或开启debug ip bgp updates。不过这类debug命令要小心用生产环境开大范围debug会瞬间刷爆CPU我通常只加peer-address参数限定单个邻居调试完立即关闭。整个排障思路其实就是一层层剥洋葱邻居会话 → 路由接收/发送 → BGP表的属性比较 → RIB安装 → 全局路由表转发。哪一层断了就在哪一层深挖。不会一步到位但每层都能找到对应的命令快速验证。7. 从“会配”到“会调”关于选路优化的进阶经验到这儿各位可能已经把核心属性和基本调试命令都消化完了。可如果你经常跟BGP打交道一定会有种感觉能配置是一回事调得好不好是另一回事。最后我想分享几条进阶经验它们不是标准教科书里会写的但对实际网络“手感”的提升帮助很大。7.1 永远把“稳定性”放在“最优”之前BGP的基因是稳定性优先。所以我在做任何调优前都会先问自己一个问题这个改动会不会导致路由震荡把一条路由从一个出口切到另一个出口哪怕策略上完全可行也要考虑对业务的影响面。最稳妥的做法是先在测试环境或维护窗口内做小范围验证观察一段时间的选路稳定性和流量曲线确认没有抖动了再全量下发。生产网络里稳定性就是最大的可用性。7.2 不要迷信“唯一正确答案”属性参数本身就是可调参数我碰过不少同行在调LOCAL_PREF或MED时会把某个数值当成“神谕”比如LOCAL_PREF一定要200MED一定要100。其实BGP选路中的属性数值只是相对大小重要的是“比较关系”而不是“绝对数值”。你能在合理范围内灵活调整是为了适应不同的链路质量、成本和策略。比如主备链路的LOCAL_PREF差50还是差150取决于你对主链路的“偏爱程度”以及备份链路的承载能力——给备份链路留出足够的“触发空间”但也不至于主链路一有风吹草动就浪费了备份能力。7.3 用“路由起源验证”来守住最后一层底线现在大规模网络都在推RPKI资源公钥基础设施和BGP安全机制很多老工程师会觉得这是运营商的事。但我建议企业网络也在Edge设备上启用“路由起源验证”配合前缀过滤这会大大降低误收恶意路由、路由劫持的风险。这也是BGP维护从“被动响应”走向“主动防御”的重要一步。技术上初期可以先开启接收RPKI无效路由的警告模式观察一段时间再决定是只接受有效路由还是预警后由人工介入。回到开头那一点BGP选路不是选“快”而是选“优”但这个“优”的标准全部沉淀在那一条条有顺序的属性规则里又有一层层本地策略和全局策略在中间博弈。希望你在读完这篇文章后能重新审视自己网络里那些“想不通”的路径选择顺着属性比较的顺序找到那个真正主导一切的关键差异。当你有一天能够不看文档就能凭show输出预判出流量该往哪走的时候你会觉得BGP这门手艺真的很有意思。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑