3. STP状态机:Blocking、Listening、Learning、Forwarding、Disabled状态详解
STP的状态机,说白了就是交换机端口在生成树协议下的「人生五阶段」。我刚入行那会儿,总觉得这五个状态记起来麻烦,后来在项目里吃过一次亏——一个端口莫名其妙卡在Learning状态,业务中断了十几秒。嗯,从那以后,我把这五个状态刻在了脑子里。
今天咱们就一个一个掰开揉碎了讲。你想想看,一个端口从开启到最终转发数据,中间要经历哪些「心理活动」?
3.1 状态总览:一张表说清楚
先给你一张速查表。我个人习惯把这五个状态分成两类:稳定状态和过渡状态。
| 状态 | 是否转发数据 | 是否学习MAC | 是否处理BPDU | 持续时间 | 类型 |
|---|---|---|---|---|---|
| Disabled | 否 | 否 | 否 | 永久(手动关闭) | 稳定状态 |
| Blocking | 否 | 否 | 是(接收但不发送) | 20秒(Max Age) | 稳定状态 |
| Listening | 否 | 否 | 是 | 15秒(Forward Delay) | 过渡状态 |
| Learning | 否 | 是 | 是 | 15秒(Forward Delay) | 过渡状态 |
| Forwarding | 是 | 是 | 是 | 永久 | 稳定状态 |
注意看,从Blocking到Forwarding,最少要等30秒(15+15)。这就是STP收敛慢的根本原因。我在项目中遇到过客户抱怨「交换机重启后要等半分钟才能上网」,其实就是这个道理。
3.2 Disabled状态——端口「躺平」了
Disabled,字面意思就是「禁用」。这个状态最简单——端口被管理员手动shutdown了,或者物理链路断了。
在这个状态下,端口什么都不干:
- 不转发数据帧
- 不学习MAC地址
- 不处理也不发送BPDU
说白了,端口就像被拔了电源。你执行 interface GigabitEthernet0/1 然后 shutdown,端口就进入Disabled状态。
3.3 Blocking状态——「只听不说」的观望者
Blocking状态,是STP端口最开始的稳定状态。端口刚启动,或者从Forwarding被踢回来,都会先进入Blocking。
这个状态的特点很鲜明:
- 不转发数据——这是最重要的,防止环路
- 不学习MAC——MAC表里不会有这个端口的记录
- 接收BPDU——但绝不发送BPDU
为什么会这样?你想想看,如果端口在Blocking状态下还发送BPDU,那它就会参与根桥选举,可能把网络搞乱。所以STP设计得很聪明——Blocking端口只「听」不「说」。
我记得有一次排查环路问题,发现一台交换机的某个端口一直在Blocking和Listening之间来回跳。后来发现是BPDU报文被误丢弃了,导致端口收不到足够的BPDU信息,状态不稳定。
show spanning-tree interface gigabitEthernet 0/1 查看端口状态。如果看到 "Blocking",别慌,这可能是正常的——说明STP在保护你的网络。
3.4 Listening状态——「过渡期」的倾听者
从Blocking到Forwarding,中间要经过Listening。这个状态持续15秒(Forward Delay计时器)。
Listening状态下:
- 仍然不转发数据
- 仍然不学习MAC
- 可以发送和接收BPDU——这是关键变化
为什么需要Listening?说白了,就是给STP一个「重新选举」的时间窗口。端口在这个状态下,会积极参与BPDU交换,重新确定自己在生成树中的角色。
我曾经在数据中心项目里,为了缩短这个15秒的等待时间,把Forward Delay从15秒改成了10秒。结果呢?网络拓扑变化时出现了短暂的环路,广播风暴差点把核心交换机打趴下。嗯,从那以后我再也不敢随便改这个参数了。
3.5 Learning状态——「边听边记」的学习者
Listening结束后,端口进入Learning状态。这个状态也持续15秒。
Learning状态和Listening最大的区别在于:
- 开始学习MAC地址——这是质的飞跃
- 仍然不转发数据
- 继续发送和接收BPDU
你可能会问:为什么不直接进入Forwarding,非要再等15秒?
原因很简单——防止MAC表震荡。你想想看,如果端口一进入Forwarding就开始转发数据,但MAC表里空空如也,那所有未知单播帧都会被泛洪,造成不必要的广播。Learning状态给了端口15秒的时间,先把周围设备的MAC地址学个七七八八,等进入Forwarding时,大部分流量就能精准转发了。
我个人习惯把Learning状态比作「运动员上场前的热身」——虽然还没正式比赛,但已经在活动筋骨了。
3.6 Forwarding状态——「火力全开」的正式工
终于到了Forwarding状态。这是每个端口梦寐以求的「转正」时刻。
Forwarding状态下:
- 转发数据帧——正常工作了
- 学习MAC地址——持续更新MAC表
- 发送和接收BPDU——维持STP拓扑
端口一旦进入Forwarding,就说明它在生成树中找到了自己的位置——要么是根端口(Root Port),要么是指定端口(Designated Port)。
3.7 状态转换的完整流程
咱们把整个过程串起来,看看一个端口从插上网线到正常工作的完整心路历程:
- 端口UP → 进入Blocking状态(等待20秒Max Age)
- Blocking结束 → 进入Listening状态(等待15秒)
- Listening结束 → 进入Learning状态(等待15秒)
- Learning结束 → 进入Forwarding状态(正常工作)
总耗时:20 + 15 + 15 = 50秒?不对!
这里有个细节:端口刚启动时,如果它认为自己是指定端口,会直接跳过Blocking,从Listening开始。所以实际等待时间通常是15+15=30秒。但如果端口收到更优的BPDU,它就会留在Blocking状态,等待Max Age超时(20秒)后再进入Listening。
我曾经在项目里用Wireshark抓包,亲眼看到端口从Blocking到Forwarding花了整整35秒。原因就是网络中有两台交换机在争抢根桥角色,BPDU来回拉扯,导致状态机反复重置。
3.8 避坑指南:状态机相关的常见问题
- 坑1: 把Forward Delay改得太小。我试过改成4秒,结果网络拓扑变化时出现了环路,广播帧把CPU干到了100%。建议: 除非你非常清楚自己在做什么,否则保持默认值15秒。
- 坑2: 误以为Blocking状态的端口不处理BPDU。实际上Blocking端口会接收BPDU,只是不发送。如果你在Blocking端口上抓包,能看到它一直在收BPDU。
- 坑3: 把Disabled和Blocking混为一谈。Disabled是管理员手动关闭,Blocking是STP协议自动决定的。两者性质完全不同。
debug spanning-tree events 可以实时查看端口状态变化。但注意,在生产环境慎用debug,CPU会飙升。我一般先在测试环境模拟拓扑变化,确认没问题了再上生产。
3.9 快速记忆口诀
最后,送你一个我自己编的口诀,方便记忆这五个状态:
Disabled:端口已关闭,啥也不干
Blocking:只听不说,防止环路
Listening:边听边说,但不学习
Learning:开始学习,但不转发
Forwarding:火力全开,正常干活
记住这个顺序:D → B → L → L → F。嗯,虽然有两个L容易混淆,但你只要记住「先听(Listening)后学(Learning)」的顺序,就不会搞错。
好了,STP状态机就讲到这里。下一章咱们聊聊RSTP(快速生成树协议),看看它怎么把30秒的收敛时间缩短到几毫秒。到时候你会发现,理解了这五个状态,RSTP的那些改进就很好理解了。