首页 / 资讯中心 / 文章详情

STP生成树协议实战:阻塞端口选举与二层环路故障排查

STP生成树协议实战:阻塞端口选举与二层环路故障排查 ★ FEATURED ARTICLE
先讲一段差点把我之前所在办公网搞崩的经历。那天网络莫名卡顿核心交换机CPU飙升PC之间时通时断连ARP都出现大量冲突。排查到后来才发现原因是有人图方便在交换机A和交换机B之间多接了一根网线形成了物理环路。那一刻我才真正意识到STP生成树协议这套平时被当成“默认开启就行”的协议在关键时刻能救整个网络的命而它的“阻塞端口”正是解决二层环路的灵魂。所以我一直建议网络方向的朋友不管你是准备认证考试还是已经在干运维都值得亲手搭一个双链路拓扑把STP的选举过程和阻塞端口行为完整跑一遍。这篇文章就是我基于完整实验过程整理出来的从环路故障复盘、STP选举原理到环境搭建、抓包验证、故障切换时间轴再到RSTP和MSTP的实验延伸。内容尽量按“我真实做过”的口吻写该给命令行的地方给命令该给数据的地方给数据你照着操作就能复现。1. 为什么要较真这套协议一次真实的二层环路故障复盘1.1 一根多余网线引发的“全网大堵车”先说故障本身。之前某公司内部有一台文件服务器终端用户集中在一个网段网络拓扑本来很简单两台接入交换机分别连到核心PC挂在接入交换机上互不相干。某天为了临时扩展工位有人把交换机A的一个空闲口和交换机B的一个空闲口用网线直连了。就这么一根线整个局域网从“稳定”变成“半瘫痪”。原因并不复杂。二层交换机收到广播帧或者未知目的MAC的数据帧时会从接收端口以外的所有端口泛洪出去。本来一个广播帧只会被转一圈现在有了A到B、B到A这个环形路径广播帧就会在两个交换机之间无限循环每转一圈就会被复制一份频率越来越高。很快所有交换机的端口吞吐被这些无效帧打满CPU也要花大量资源处理重复帧。更麻烦的是MAC地址表抖动。交换机靠源MAC地址学习端口对应关系。环路存在时同一个MAC地址可能在短时间内先出现在A的G0/0/1又被从B的方向学习到A的G0/0/2于是交换机的MAC表项在两个端口之间反复横跳转发决策完全失效。实测的现象就是PC的ping一会儿通一会儿丢包文件服务器基本连不上全网都在广播风暴里“空转”。1.2 为什么不能靠“人肉拔线”解决你可能会说既然是网线接错了拔掉不就完了道理没错但生产网络不可能因为怕环路就不要冗余链路。正常的高可用设计里交换机之间往往故意保留多条物理链路业务走主链路备用链路随时待命。问题是二层网络天生不认“主备”它只会按照转发规则把帧从所有能走的路径泛洪出去。如果没有协议来协调哪条链路转发、哪条链路停车冗余链路越多风暴越猛。STP就是那套“红绿灯系统”它通过阻塞端口把物理上的环路逻辑上打断让全网在任意时刻都只有一个无环的树形转发路径。一旦正在转发的链路故障阻塞端口立刻转变角色接替工作。堵哪条、放哪条全部由协议自动计算不需要人工干预。1.3 这个实验适合谁、需要什么条件我觉得这三类人特别适合把这个实验做一遍一是刚开始学交换技术、对STP只有概念没有手感的学生二是已经在做网络运维、遇到过环路故障但没真正抓过BPDU的工程师三是准备网络认证、被各种端口角色和状态机绕晕的考生。实验条件非常低。最理想的是两台真实交换机加两台PC再加一根多余的网线。没有真实设备也没关系主流网络模拟器完全够用。整个实验从搭拓扑到做完抓包和故障切换大约一小时。重点不是背命令而是观察端口角色怎么变、BPDU从哪里来、阻塞口在故障时如何“由堵变通”。2. 动手之前先把选举逻辑吃透STP的四类角色与端口状态机2.1 从物理环到逻辑树STP到底在“剪”什么STP的全称是Spanning Tree Protocol中文叫生成树协议。核心思想可以理解成一句话把存在物理环路的二层网络通过逻辑上阻塞某些端口改造成一棵无环的树。这里的“树”只是逻辑概念物理链路一根都不会少。它不像你去修剪花园把多余枝条直接剪掉而是让某些端口“保持待命但不转发业务数据”。这样既保留了冗余链路的可用性又避免了广播帧在环路里无限兜圈子。我用一个生活化的类比这就像繁忙路口设置的单行道。道路都修在那里但系统规定哪个方向能走、哪个方向暂时封闭。一旦主路发生事故封闭的道路会重新开放。STP阻塞端口就是那条“暂时封闭、但随时待命”的路。2.2 四类角色的选举规则STP会给每种端口分配一个角色。整个选举分四步参与比较的关键信息按优先级排列。第一步全网选出一个根桥Root Bridge。每台交换机都有一个桥ID由两部分组成优先级默认32768加上MAC地址。桥ID越小越优先比优先级再比MAC地址。数值越小越有机会成为根桥。第二步每个非根桥交换机选出一个根端口Root Port。根端口是“本交换机上距离根桥最近”的端口判断依据是根路径开销也就是从本端口到达根桥所经过的链路开销总和。开销越小越优。第三步每条链路的两个端点之间选出指定端口Designated Port。比较标准是“谁离根桥更近”也就是携带的根路径开销更小如果两边开销一样就继续比发送者的桥ID最后比端口ID。第四步落选的端口进入阻塞状态。所谓阻塞端口就是既不是根端口也不是指定端口的端口它在逻辑上被“关”起来不转发业务数据。角色选举范围主要比较依据能否转发业务数据根桥全网桥ID最小它是全网的中心所有指定端口都在它上面根端口每台非根桥交换机到根桥的路径开销最小可以转发指定端口每条链路两端到根桥的路径开销更小可以转发阻塞端口全网剩余端口上述比较全部落选不可以转发仅监听BPDU2.3 端口状态机里的五个阶段标准的STP端口有五种状态从端口物理开启到正常转发需要经历一个状态迁移过程。Disabled禁用端口被管理员关闭或者物理链路不通不参与任何STP计算。Blocking阻塞端口不转发数据帧不学习MAC地址但会持续监听BPDU等待拓扑变化。Listening监听端口开始参与生成树计算能收发BPDU但仍然不学习MAC、不转发数据。Learning学习端口开始学习MAC地址但依然不转发业务数据。Forwarding转发端口正常收发BPDU和业务数据链路真正进入可用状态。状态接收BPDU发送BPDU学习MAC地址转发业务数据Disabled否否否否Blocking是否否否Listening是是否否Learning是是是否Forwarding是是是是这里有个新手最容易忽略的重点阻塞端口虽然不转发数据但它并没有“死掉”它仍然在接收BPDU。这也是实验里抓包能抓到根桥BPDU的原因。2.4 看懂BPDU实验就成功了一半STP的决策完全依赖BPDUBridge Protocol Data Unit报文。BPDU相当于网络里的“选举传单”里面携带了根桥ID、根路径开销、发送者桥ID、发送端口ID等关键字段。协议定义了几个重要定时器Hello Time默认2秒根桥每隔2秒发送一次BPDUMax Age默认20秒交换机如果超过这个时间没有收到对端BPDU就认为链路出了问题开始重新收敛Forward Delay默认15秒这是Listening和Learning阶段各需要的时间。以根桥为例根桥主动周期性发送BPDU其他交换机从根端口收到之后再通过自己的指定端口向下游转发。整个网络的生成树信息就是这样一层一层传递下去的。这也是为什么阻塞端口“虽然不转发数据但一定不能停止听BPDU”因为它是备用链路能否在主链路故障时快速接管的关键。3. 实验环境搭建从零复现一个单点环路拓扑3.1 拓扑怎么摆这个实验我建议用两张交换机和两张PC来搭模拟器或真实设备都可以。我给交换机编号为SW-A和SW-BPC-A接SW-A的G0/0/10PC-B接SW-B的G0/0/10。关键步骤是让SW-A和SW-B之间接两条链路SW-A的G0/0/1连SW-B的G0/0/1SW-A的G0/0/2连SW-B的G0/0/2。这样一来数据从SW-A出发既可以走第一条链路也可以走第二条链路物理环路就形成了。如果你用的是真实设备一定注意先把交换机的STP保持默认开启状态再接线不要在没有生成树保护的情况下先造成环路。模拟器操作风险低一些但也应该养成“先开启STP再接冗余线”的习惯。如果你手上只有一台交换机也可以做简化版在一台交换机上加两根网线连接另一台设备本质不变仍然是环形路径只是设备数量少一半。3.2 最少配置三条命令不同厂商的CLI风格有差异这里以某类主流设备的命令格式为例核心逻辑在所有设备上一致。配置第一步确保全局开启STP。某交换机SW-A: [SW-A] stp enable第二步为了让实验结果可控我通常会把SW-A的桥优先级调小让它稳定当选根桥。桥优先级默认是32768最小值可以调到0但要注意实际设备往往要求优先级必须是4096的倍数。这里我调到4096。[SW-A] stp priority 4096第三步查看全网生成树信息确认端口角色。[SW-A] display stp brief [SW-B] display stp brief实际实验中建议先在默认优先级下启动协议观察一次再修改优先级观察变化。两步对比你对“桥ID越小越优”的理解会比只看文档深得多。3.3 默认状态下的角色分配观察一开始我保持两台交换机优先级相同都是32768。这时谁当根桥取决于谁的MAC地址更小。在我的实验里SW-A的MAC地址更小所以SW-A成为根桥。在SW-B上执行display stp brief你会看到大致这样的角色分配SW-B的G0/0/1成为根端口G0/0/2成为阻塞端口。SW-A的两个端口都是指定端口因为它们直接连接在根桥上根路径开销最小。阻塞端口出现在SW-B的G0/0/2这个位置不是随机产生的而是由选举规则决定的根桥已经占据了SW-A的G0/0/1和G0/0/2SW-B的两个端口到根桥的开销一样但其中一个端口ID更优于是它成为根端口另一个成为阻塞端口。你可以尝试把优先级改成4096再观察一次。SW-A变成根桥之后SW-B上仍然是两个端口二选一但如果你想改变哪条链路转发、哪条链路阻塞就需要调节开销或端口优先级。3.4 先验证“冗余”这条路配置完成后PC-A和PC-B之间用连续ping做连通性测试。正常情况下应该全程无丢包STP已经通过阻塞一个端口消除了环路业务流量走根端口路径稳定转发。接下来做一个刺激一点的验证把SW-A和SW-B之间的主链路拔掉。你会发现PC之间的ping会断掉几秒到几十秒然后恢复。这段时间就是STP重新收敛的过程。阻塞端口检测到原链路故障后开始从Blocking状态向Forwarding状态迁移最终两条链路之间只剩一条网络自动愈合。这里的“自动愈合”就是冗余的意义。没有STP的时候拔掉这条线物理环路可能消失但网络不会因为这个动作而死真正危险的是多接出来的那条线而STP让这种“多接”变得可控。4. 阻塞端口实验的核心验证抓包看BPDU观察“由堵变通”4.1 在阻塞端口上挂抓包如果只看端口状态表和指示灯你对“阻塞”的理解会停留在表面。我建议一定做一次抓包验证看阻塞端口到底在干什么。在SW-B的G0/0/2这个阻塞端口上做镜像抓包或者用模拟器自带的报文捕获功能抓取一段时间的报文。过滤条件很简单STP的BPDU有两种常见的EtherType标识你只要注意抓到的二层报文是不是发往组播目的地址01:80:c2:00:00:00或者01:00:0c:cc:cc:cd这类STP专用MAC就能确认抓到的是BPDU。我实验里抓到的结果非常规律阻塞端口虽然不转发任何业务数据帧但每2秒都会收到一条来自根桥方向的BPDU。这就是我前面强调的“堵塞不哑火”的实证。阻塞端口一直在听BPDU等于随时监听网络中是否有更优的生成树信息或者根桥是否失联。4.2 让“备胎”转正的两种手段实验做熟之后可以主动控制哪条链路当主链路。最常用的两个调整手段是链路开销和端口优先级。端口开销的调整思路很简单把想让业务流量走的链路开销调小或者把另一条链路的开销调大STP就会自动重选根端口。以SW-B为例我把原本阻塞的G0/0/2的端口开销改成比G0/0/1更小。某交换机SW-B: [SW-B] interface GigabitEthernet 0/0/2 [SW-B-GigabitEthernet0/0/2] stp cost 1改完之后再看display stp brief你会发现SW-B的G0/0/2从阻塞角色变成了根端口原来的G0/0/1反而变成阻塞端口。一条命令下去主备链路直接对调。如果两条链路的速率相同开销相同还可以通过修改端口优先级来影响选举。端口优先级默认128值越小越优。[SW-B] interface GigabitEthernet 0/0/2 [SW-B-GigabitEthernet0/0/2] stp port priority 16实际工作中我更推荐通过调整cost来引导流量因为cost能反映真实的物理带宽而端口优先级更适合在同带宽条件下做精细的定向牵引改错了容易让流量走一条意想不到的链路。4.3 一次故障切换的完整时间轴这个环节是整个实验里最值得记录的部分。我拔掉SW-B根端口所在的那条链路同时在PC-A上持续ping PC-B并在另一台终端抓取SW-B阻塞端口的状态变化。实验记录大致如下时间点事件端口状态0秒根端口所在链路物理DownBPDU中断原阻塞端口仍处于Blocking020秒SW-B等待Max Age超时持续接收不到根桥BPDUBlocking → Listening20秒进入Listening阶段开始参与生成树计算Listening35秒Listening结束进入Learning阶段学习MAC地址Learning50秒Learning结束进入Forwarding业务流量恢复Forwarding也就是说从链路故障到备用链路真正接管标准STP大约需要50秒。前20秒是Max Age等待后面各15秒分别是Listening和Learning。这50秒内PC之间的ping会出现明显中断具体断几个包取决于ping间隔。4.4 实验里最容易翻车的三个操作细节我第一次做这个实验时翻了三次车都值得提醒你注意。第一修改配置后没有保存。模拟器还好真实设备如果直接断电重启配置回到默认你会看到一个“角色分配和自己预期完全不符”的结果。改完配置务必执行保存命令让实验结果可复现。第二抓包端口选错。你在SW-B上想观察阻塞端口却把抓包工具挂在了根端口上结果看到的一直是正常转发的BPDU永远看不到“阻塞端口也在监听到BPDU”这个关键结论。抓包之前先确认当前端口的STP角色。第三拔线之后没有恢复。故障切换演示做完如果你不把拔掉的链路接回去整个实验环境就变成了单链路拓扑后续再做“修改cost导致角色互换”就会看不到任何变化。每次实验操作都要有意识恢复现场。5. 协议机制的模糊地带半数人实验做到这就翻车5.1 两条链路cost相同凭什么它是阻塞很多人在实验里会遇到一个困惑两条链路速率一样cost一样为什么阻塞的总是G0/0/2而不是G0/0/1原因在于STP的选举不是“看心情”而是严格按顺序比较先比到达根桥的根路径开销再比发送者桥ID最后比发送端口ID。当根路径开销相同、桥ID也相同时端口ID就变成决定因素。SW-B的两个端口如果cost相同那么端口ID较小的一方会获得指定端口或根端口资格另一方落入阻塞。建议你在实验里用display stp brief仔细观察端口ID。有些模拟器显示的是端口编号本身有些显示的是“端口优先级端口号”组合值。弄清楚这个字段你就不会觉得阻塞是“随机”的了。5.2 链路速率不一致造成的路径选择“颠倒”还有一类情况更容易让初学者懵主链路用的百兆备用链路用的千兆结果STP自动把千兆链路选成活跃路径百兆反而被阻塞。这符合协议逻辑却不符合网络规划直觉。常见的链路开销参考值大致如下链路带宽端口开销参考值10 Mbps100100 Mbps191 Gbps410 Gbps2不同标准和不同设备实现可能有差异但大体趋势一致带宽越大开销越小。实际规划中如果希望特定链路成为主路径必须主动用cost来引导而不是想当然认为标着“主”的那条线就一定是主。5.3 为什么不要用手工shutdown替代阻塞有些同学做实验图省事直接用一个shutdown命令把冗余端口关闭认为这也算“阻塞”。这种操作在实验里也许能防止环路但在生产环境里等于放弃了STP的自动故障恢复能力。手工关闭的端口不会接收BPDU也不会在拓扑变化时自动切换它就是一个被“拔了线”的端口。而真正的STP阻塞端口始终处于监听状态每2秒收到的BPDU就是它的“心跳信号”。一旦主链路故障BPDU中断阻塞端口会依据超时机制自行进入Listening、Learning、Forwarding流程接管业务。这个能力是手工shutdown给不了的。5.4 真实网络里的“假环路”与防护建议物理拓扑明明只有一根线但网络还是出现了环路故障这种情况也不少见。常见原因包括trunk放行过多VLAN导致两个交换机之间出现逻辑上的冗余路径或者用户私自接入了一个小交换机到办公口形成“二层环路”。这类问题在实验里不容易复现但在生产网络里非常典型。我的建议是养成三个习惯。第一全网开启STP不要为了优化性能贸然关闭。第二对接入终端的边缘端口启用端口快速转发机制PortFast和BPDU保护BPDU Guard这样交换机不会因为误接设备而产生环路。第三监控STP角色变化和拓扑变更告警一旦有频繁的角色切换马上排查是否有新增链路。6. 实验做完之后顺势把RSTP和MSTP也跑一遍6.1 RSTP为什么能把50秒压到秒级标准STP 50秒左右的收敛时间在生产网络里很致命于是有了RSTPRapid Spanning Tree Protocol快速生成树协议。它把端口状态精简为Discarding、Learning、Forwarding三种角色则增加了替代端口和备份端口但最核心的变化是引入了提议-同意Proposal/Agreement握手机制。简单理解在RSTP里指定端口可以直接向上游发送“提议”如果上游确认同意端口立刻进入Forwarding不再傻等15秒的Listening和Learning。配合边缘端口秒开整个收敛过程可以从50秒级别压缩到秒级甚至毫秒级。对比项STPRSTP端口状态数量5种3种是否依赖定时器倒计时是否靠P/A握手边缘端口不支持支持替代端口描述落选端口称为阻塞口明确分为替代端口和备份端口典型收敛时间约50秒秒级建议你在同一套双链路拓扑里把STP协议切换到RSTP再重复一次拔线实验。观察到的收敛时间会比50秒短得多这就是协议演进带来的实际价值。6.2 MSTP把“一棵树”拆成“多棵树”如果整个网络所有VLAN都走同一棵生成树链路利用率往往不高一条链路在跑另一条链路闲着。MSTPMultiple Spanning Tree Protocol多生成树协议解决的就是这个问题。MSTP允许把多个VLAN映射到同一个生成树实例不同实例可以独立计算各自的阻塞端口。比如VLAN 10映射到实例1VLAN 20映射到实例2实例1让第一条链路活跃实例2让第二条链路活跃两个VLAN的流量就能在不同链路上分流。做这个扩展实验你只需要在两台交换机上分别创建两个MST实例把VLAN映射进去再观察不同实例的阻塞口出现在哪里。实验结果往往比单生成树更贴近企业网络的真实规划。6.3 我个人建议的实验拓展路径比起一遍遍背OSI模型我更喜欢用“实验线”来带新手先做标准STP再切RSTP最后上MSTP。每切换一次就把同样一份“看角色、抓BPDU、拔线测收敛”的流程重跑一遍。我自己的习惯是每次实验都把display stp brief的输出截图或保存成文本标注好当时的拓扑和改动后续排查问题直接翻邮件和截图对比。时间长了你能形成的判断直觉非常可怕看到端口指示灯狂闪、CPU异常升高几秒钟内就能把怀疑范围锁定在二层环路而不是去重启光猫或者怀疑外网跑路。等到这一步这个STP实验就算真正做到了“从实验里长出经验”。
阅读完成 · 觉得有帮助?
咨询建站