1. 先搞清楚为什么默认情况下BGP不走负载分担做网络的人基本都遇到过这个场景明明两个运营商出口都有带宽冗余可流量就是死认一条路走另一条链路闲得发慌。业务方天天问为什么买了双线带宽只跑出一条线的效果问题大概率出在BGP选路机制上它天生只认“最优路径”不认“多条路径”。BGP是路径向量协议核心任务是维护路由表里每一条前缀的“最优路径”。它通过一堆选路规则Local Preference、AS Path长度、MED、下一跳IGP度量等逐条比较最终只选出唯一一条最优路由放进IP路由表。这个设计在传统互联网架构里没毛病——自治域之间本来就该有清晰的流量流向避免路径混乱。但放到现代数据中心、多出口园区网、双线接入IDC这些场景里就有点浪费带宽了明明两条物理链路都是可达的却因为选路规则决出胜负另一条就晾着吃灰。负载分担解决的就是这个问题让BGP在满足条件的前提下把流量同时分担到多条等价路径上。它不改变选路规则的优先级顺序只是让多条路径同时进入路由表并参与转发。底层原理类似于ECMP等价多路径但BGP层面的负载分担比IGP复杂得多因为它不仅涉及“怎么转发”还涉及“路由表如何生效”“邻居如何处理下一跳”“不同厂商的实现差异”等一系列问题。这篇文章适合三类人一是刚接触BGP想做多出口负载分担的网络工程师二是被“流量走单条”问题折磨的运维朋友三是想系统梳理BGP路径选择与转发关系的进阶学习者。我会按“为什么默认不负载 → 什么条件才能负载 → 怎么配置 → 踩过什么坑”的逻辑把整个链路讲透。2. 负载分担的核心思路从“选一条最优”到“同时用多条”2.1 等价多路径与BGP负载分担的关系很多人把“BGP负载分担”和“ECMP”混为一谈其实它们是两码事。ECMP是转发层面的能力当IP路由表里同一个前缀存在多条等价路由时转发芯片可以把流量分摊到这些出接口上。而BGP负载分担是控制层面的决策让BGP路由表里同时保留多条到达同一前缀的路径并把这些路径下发到IP路由表。所以两者是配合关系“BGP负载分担是产生多条路由的方式ECMP是让多条路由真正分流的能力”。如果设备只支持BGP多路径但不支持ECMP转发老一辈的某些设备就有这个问题那配置了负载分担也白搭路由表里看到多条转发还是走一条。要实现BGP负载分担必须满足几个硬性条件多条路径的选路属性必须完全“平手”。也就是说在BGP选路规则逐条比较的过程中Local Preference相同、AS路径长度相同、MED相同、起源类型相同一路比下来分不出胜负才会触发多路径判定。但凡有一条路径在某个属性上占优负载分担就不会发生。这里有一个关键细节BGP负载分担不要求“IGP度量相同”。IGP度量只在选路的最后阶段用于打破平局但进入多路径计算时只要前面的属性都一致即使下一跳的IGP度量不同也可以形成负载分担。但需要注意如果只是IGP度量不同实际转发时流量还是会偏向度量更优的那一跳——很多厂商的实现里会通过调整转发权重Weight来修正这个偏差这算是一个隐藏坑后面排查部分再展开。2.2 非等价场景负载分担不是只能“五五开”等价多路径是负载分担的“标准形态”但生产环境里真正完美的等价链路并不多。更多时候是两条链路带宽不同比如一条10G专线、一条1G互联网出口你总不能让它们等权分流否则1G那条会直接被冲垮。于是就有了非等价负载分担的需求。BGP层面怎么处理常见思路有几种一是通过BGP Link Bandwidth链路带宽扩展团体属性传递带宽信息让设备根据带宽比例自动计算转发权重二是通过策略人为调整路由属性比如给权重链路的路径加偏好让流量“按需倾斜”三是在IGP层面使用等价路由的非等权ECMP但需要设备支持UCMP。但必须说清楚BGP自身没有原生的UCMP能力。真正实现非等价分流要么靠Link Bandwidth扩展属性这需要所有设备都支持而且配置比较冷门要么靠“把大链路拆成多条等价会话”这种工程手段——比如一条10G链路拆4个等价的BGP会话配合ECMP形成加权效果。这种拆会话的做法虽然土但在很多现网里确实有效而且比调Link Bandwidth更容易控制。2.3 负载分担与选路策略的边界做负载分担最忌讳的一件事为了做负载而打破原有的选路策略。BGP的选路规则是经过精心设计的层次化决策Local Preference用于域内策略控制AS Path用于域间优选MED用于邻居间协商。如果你为了强行让两条路径变成等价关系把Local Preference或MED改成相同值那等于把策略层的控制手段废掉了。工程上的正确做法是先确定哪些前缀需要负载分担再针对这些前缀检查它们的选路属性是否天然等价如果不等价再决定是否值得通过策略调整比如调整MED、AS Path prepend来让它们等价。永远不要全网一刀切地开启负载分担。BGP负载分担适合的是“确定性场景”——比如两个运营商出口收到的默认路由、数据中心到同一上游的两条专线这类路径天然具备等价条件直接启用ECMP即可。3. 实操BGP负载分担的配置与部署3.1 配置前的网络设计检查清单动手配配置之前先花十分钟做自查。我在现网里见过太多“照着文档配完但流量死活不均衡”的案例十有八九是前置条件没满足。按下面这张清单逐项确认基本能排除80%的问题。检查项确认内容影响硬件与软件版本设备是否支持BGP多路径与ECMP转发新版支持、老版本可能只存储不转发路径属性一致前缀的LocalPref、AS Path、MED、起源类型是否一致任何一个属性不同都会导致选路早停邻居类型eBGP与iBGP的负载分担配置相互独立有的设备eBGP和iBGP多路径数量分开控制下一跳可达多个下一跳必须都能通过IGP到达下一跳不可达会导致路由无法下发设备厂商差异不同厂商对等价判定的粒度不同华为/思科/华三配置格式与语义有差异转发模式逐流还是逐包转发业务是否允许乱序逐包模式在TCP长连接场景下会造成重传风暴默认路由与明细路由明细路由和默认路由的负载分担行为不同默认路由做负载分担更简单明细路由需逐条检查3.2 等价多路径的核心配置思路以某主流厂商的设备为例BGP负载分担的配置路径大致分三步启用BGP多路径、设置最大等价路径数、调整转发负载方式。以下是通用化的配置骨架具体关键词以实际设备为准bgp 65001 maximum load-balancing 2 // 允许2条等价路径同时参与转发 load-balancing as-path-ignore // 某些厂商需要忽略AS路径顺序差异配置本身不复杂真正复杂的是“怎么让两条路径达到等价条件”。比如在eBGP场景从两个邻居收到的同一条前缀AS Path可能分别是“65001 65002”和“65001 65003”。这种情况下由于AS Path长度都是2天然等价直接开负载分担就能生效。但如果其中一个路径多了AS prependAS Path长度变成3那这条路径就落在后面了。这时候看你对这条链路的态度如果想让它参与负载分担就得去掉配在它身上的prepend或者给另一条也补上凑成同样的长度。iBGP场景更麻烦一些。iBGP默认不把从iBGP邻居学到的路由传给其他iBGP邻居所以跨设备做负载分担时通常要配合路由反射器或者全网状建立邻居。此外很多人没意识到从eBGP学到的路由和从iBGP学到的路由之间即使前缀相同也可能因为各种原因不满足等价条件。最典型的就是“下一跳”属性eBGP路由的下一跳通常是直连邻居地址iBGP路由的下一跳可能是远端设备的环回地址两者IGP度量不同就可能触发最后一次选路比较导致负载分担失败。3.3 逐流与逐包转发细节决定业务感受BGP负载分担配置完成后还有个容易忽略的问题流量到底怎么分摊绝大多数现代设备支持两种模式按流哈希per-flow和按包轮询per-packet。按流哈希是默认推荐模式。它根据五元组源IP、目的IP、协议号、源端口、目的端口做哈希计算把属于同一条流的报文固定送到同一个出接口。优点是不破坏TCP会话的连续性、不会乱序缺点是哈希算法可能不均匀大流量流比较多时会显得某一链路偏忙。我在现网见过哈希不均导致一条链路70%利用率、另一条只有30%的情况这并不一定是配置错了可能是哈希因子选择问题。运营商级设备通常允许你调整哈希因子比如改用“源IP目的IP”做二元哈希、或者加入“源端口目的端口”做四元哈希选哪一组因子取决于流量模型。实测经验如果流量里有很多来自同一网段的大流尽量把源端口和目的端口加入哈希因子如果业务以SSL/TLS为主注意TLS握手流和加密数据流的端口特征避免握手都挤到一条链路。按包轮询则是把每个报文轮流从不同链路发出去链路利用率最均衡但会引入乱序风险。TCP遇到乱序会触发快速重传所以按包模式基本只适合UDP或纯IP转发场景。很多设备默认不允许对TCP流量做按包负载分担即使强制开启也会用哈希因子限制设计上就是在倒逼你认真评估业务特征。3.4 非等价场景用Link Bandwidth做加权分流如果两条链路带宽差异明显比如一条1G、一条10G希望按1:10的比例分流而此时两条路径又确实等价那可以试试BGP Link Bandwidth。大致逻辑是先通过策略把链路带宽标记为扩展团体属性下发出去然后对端设备根据收到的团体属性自动计算各路径的权重实现比例转发。配置思路形如route-policy LINK-BW permit node 10 apply bandwidth 1000000000 // 标记链路带宽单位bps bgp 65001 neighbor 192.0.2.1 link-bandwidth // 向邻居通告带宽属性 maximum load-balancing 2 link-bandwidth // 基于带宽权重做负载分担说实话Link Bandwidth的标准化程度不算高跨厂商互通容易出幺蛾子。所以我更推荐另一套更“土”但更稳的方案把大链路拆成多条等价BGP会话。比如10G链路拆成4个子接口拨4个BGP邻居加上原有的1G链路5条路径在BGP层面完全等价ECMP按1:1:1:1:1转发实际加权效果就是4:1。这个方案不需要任何特殊属性只要设备子接口能力和BGP会话数撑得住就行。缺点是配置量变大、BGP会话数量变多但操作逻辑简单、排障直观适合大多数网络基础没那么强的团队。4. 常见问题与排查实录4.1 配置了负载分担但流量还是走单条这是被问得最多的问题。先说结论配置只是必要条件不是充分条件。按我自己的排查习惯顺序是“先看路由表再看转发芯片最后看流量特征”。第一步是确认BGP路由表里到底有几条路径。在设备上查看指定前缀的BGP路由明细如果只有一条“”说明选路过程没有走到多路径判定这一步。这时候排查重点放在“路径属性哪里不相等”逐项比较LocalPref、AS Path、MED、起源类型。这里有个技巧很多设备支持“对比多条路由属性”的命令可以一次性列出来对照差异比肉眼翻输出高效得多。第二步如果BGP路由表里已经有了多条路径但IP路由表只下发了一条那就是转发层面的问题。常见原因是设备对“多路径前缀下一跳”有数量限制比如只允许前4条下发或者某些板卡/芯片对该前缀的ECMP条目数有上限。这时候查看IP路由表里该前缀的标记确认是否显示“multipath”或等价路由组。没有的话要么是设备规格限制要么是软件版本的bug。第三步如果路由表和转发表都正常流量还是从单条走问题大概率出在哈希算法上。特别是流量模型不均衡时比如大量流量来自同一对IP哈希结果可能一致导致全部命中一个桶。这一步的排查手段是看接口的流量统计对比各链路出向速率差异再尝试调整哈希因子验证。4.2 负载分担导致路由震荡BGP负载分担和路由震荡的关系是很多人在现网里踩过的大坑。表现为启用负载分担后某条链路频繁up/downBGP路由在这条链路上反复撤销和通告导致前缀在“有2条路径”和“只有1条路径”之间来回跳动。问题根源在于负载分担等价条件的变化会触发路由重新选路而重新选路可能引发BGP撤回旧路径。比如一条eBGP专线闪断一下BGP session重协商期间该路径从BGP表中消失剩下那条路径成为唯一最优路径并被通告给下游。这时候如果闪断恢复较快路径回来了又回到两条等价路径的状态再次通告。频繁的回收和再通告轻则导致下游设备路由表抖动重则引发流量黑洞。工程上的解决思路有两个方向一是用BGP路由振荡抑制Route Flap Damping技术对频繁抖动的路径做惩罚让它短时间内不参与选路二是为重要的负载分担路径设置定时器缓冲区比如调整eBGP连接建立的重试间隔、保持时间Hold Time避免微短路导致会话快速重建。实操中我更推荐下面这种组合给关键链路配置链路聚合如果物理条件允许或者BFD联动检测让故障收敛变快缩短“路径缺失”的时间窗口同时把BGP的Hold Time适当加长降低微闪断触发的会话重置概率。另外一定不要忽略一个细节负载分担路径数变化会导致转发表中该前缀的ECMP条目重写而这期间如果有大批流量命中该前缀就会出现短暂丢包。所以有条件的话尽量把BGP收敛和转发面更新解耦或者把负载分担的路径数从2改成4留出冗余。4.3 下一跳不可达负载分担变成“视网膜效应”“路由表里有两条路径但转发始终只走其中一条”——这个问题的另一个常见原因是下一跳的IGP可达性不一致。BGP在决定是否下发多路径到转发表前会检查每个下一跳是否存在有效的IGP路由。如果其中一条路径的下一跳地址在IGP层面不可达比如对端设备没通告互联网段、静态路由缺失那这条路径虽然出现在BGP表里却被标记为“无效”当然不会参与转发。排在第二位的原因是IGP度量差异过大。前面提过BGP等价判定不要求IGP度量相等但有些设备在把BGP多路径下发到转发表时会参考IGP度量做加权。度量差200、500甚至上万时转发效果可能退化成几乎全部走度量小的一侧。这种问题用配置无法彻底解决正确做法是调整IGP设计让两条路径的度量尽量接近比如给较优路径人为追加度量或者干脆用权重的思路绕过去。4.4 与IGP联动时的经典坑BGP下一跳递归导致负载失效这是较深一点的坑。BGP路由的下一跳往往不是直连接口而是远端设备接口地址或环回地址。设备需要递归查找IGP路由表找到去往这个地址的出接口和路径。在复杂的网络里IGP层面到某个BGP下一跳可能本身就存在等价路径此时如果BGP侧又做了多路径负载分担整机的转发路径数就会变成“IGP等价路径数 × BGP等价路径数”。这在多数时候是好事但有一种情况会出问题当BGP多条路径的下一跳都落在同一个IGP等价组里时实际转发可能只在IGP层面做了负载BGP层面的多路径根本没有发生。比如两条BGP路径的下一跳分别是设备A的环回地址和设备B的环回地址而IGP到A和B的路径又都被聚合进一个等价组转发芯片可能将该前缀的报文全部按照IGP等价路径转发BGP层面的2条路径只用了1条。排查起来特别隐蔽看BGP路由表确实有2条路径看IP路由表也显示ECMP但接口流量统计就是一边倒。解决思路是“拆分等价域”把两条BGP下一跳规划到不同的IGP区域或不同的链路端避免它们落入同一ECMP组或者将BGP下一跳直接指向物理接口地址牺牲一些鲁棒性让递归解析的结果更确定。这块内容在常规配置手册里很少写但在运营商核心层和大型数据中心确实是高发问题。4.5 常见问题速查表症状原因排查/解决方案BGP表有2条路径路由表只有1条设备多路径下发数上限不足检查最大等价路由数配置与转发规格两条链路速率严重失衡哈希因子与流量模型不匹配更换源/目的端口哈希因子观察流量分布负载分担开启后路由频繁闪断eBGP会话微抖动触发重算缩短BFD检测时间、加长Hold Time路径属性看起来完全相同但不等价比较项遗漏如团体属性、LocalPref隐性修改用设备属性对比功能逐项核对流量走了多路径但链路利用率不均哈希不均大流集中命中单桶用五元组哈希或考虑拆粒度为会话粒度配置后转发性能下降芯片ECMP条目处理能力不足确认板卡规格必要时减少等价路径数5. 工程实践里的几点实在经验BGP负载分担做了不短时间踩的坑不少说几个个人觉得最值得分享的点。第一不要把负载分担当成“性能优化”来做而要当成“容量规划”来做。负载分担本质是让多条链路同时发挥作用但如果链路本身已经跑满了负载分担救不了你——它只是把压力分散到更多地方不能无中生有地增加总容量。所以上线前算清楚业务模型、峰值带宽、每条链路可承载的量再决定开不开、开几条等价路径。盲目开到4条甚至8条只会让故障影响面扩大任何一条链路出问题流量都会重新分布到其他链路可能瞬间打爆剩余链路。第二实际部署时优先考虑“局部负载分担”而不是全局开启。比如只对“到某运营商的出口默认路由”“到某核心业务网段的明细路由”做负载分担其他路由保持严格选路。全局启用BGP负载分担的后果就是路径选择失去策略性某些不该绕行的流量绕到远端延迟飙升。逐前缀设计负载分担策略看起来配置复杂但运维可控性会好很多。第三监控一定要看链路利用率分布而不仅仅是BGP表状态。BGP表里有几条等价路径不等于流量按预期分布在对应链路上。我的习惯是建立一套按接口出口方向的流量监控视图结合BGP路由状态做关联分析。当链路利用率偏差超过预期比如30%以上理论上限但仍出现单边高负载时立刻检查哈希因子、检查等价路径是否需要扩到更多条。这套思路在多次故障里帮我快速定位了问题比单纯看BGP路由表可靠得多。第四也是最后一点经验提一下任何一次负载分担变更都安排在业务低峰期做并且要准备好一键回滚方案。BGP负载分担的变更涉及路由表重建和转发表更新影响范围往往比预期大。我在某次操作中只改了一条路径的MED值想实现非等价分流结果影响了相邻前缀的选路导致一批流量走了跨域路径业务侧延迟报警秒上。从那以后我的变更习惯是先做离线推演再在维护窗口执行并且在变更前保存好原配置和路由快照。BGP负载分担这条路没有“一配了之”的终点网络是活的流量模型会变、带宽规划会变、链路质量会变负载分担的策略也需要跟着周期性复盘和调整。把这个机制真正吃透了至少在遇到“两条链路一条挤爆一条闲着”的时候你知道该从哪里下手。