本页课程原文(点开阅读)

STP 生成树协议

课程(6 节,按顺序学)

第 1 课 · 为什么需要 STP

入门 · 约 8 分钟

本课目标:接上「网络二层」模块留下的问题,看清 STP 要解决的那个矛盾。

先回顾问题

在网络二层模块里你已经看到了:

拓扑里只要有环路,一个广播帧就会永远转下去、副本指数级翻倍 ——
因为以太网帧头里没有 TTL。

结果是三个症状同时发生:广播风暴 + MAC 表震荡 + CPU 打满,
而且连管理口都登不上去,只能到机房拔线。

★ STP 就是这个问题的标准答案。

★★ 但要先想清楚那个矛盾

很多人的第一反应是「那就别接环路啊」。这个想法是错的,
因为冗余链路本身是好事 —— 你接第二条线的目的就是「一条断了另一条顶上」。

去掉冗余,等于用「单点故障」换「不会有环路」,这笔交易不值。

★★★ 所以真正的需求是:有冗余,但同时只用一条。
STP 干的就是这件事:
· 在所有链路里算出一棵生成树(树天然无环)
· 把多余的链路阻塞掉(不转发数据,但保持监听)
· 主链路断了,被阻塞的端口自动接管

★ 「阻塞」不等于「关闭」

这是最容易误解的一点。被阻塞的端口:

· ❌ 不转发任何用户数据帧 → 所以环路被打断了
· ✅ 但照样接收 BPDU → 所以它能一直盯着拓扑变化

正因为它一直在听,主链路一断它才能顶上来。
如果真把它关了,冗余就白接了。

动手:看树是怎么成型的

去拓扑与桥 ID页。当前是三台交换机的三角环路。

★ 看画布:有一条链路被画成了红色虚线 —— 那就是被阻塞的。
数一数:3 台设备、3 条链路,阻塞 1 条之后剩 2 条 ——
恰好是「点数 − 1」,也就是一棵树。

实验重点

  • ★★★ STP 要解决的矛盾:冗余是好事,但同时用两条就是环路
  • 答案:算一棵生成树,把多余的链路阻塞掉
  • ★ 阻塞 ≠ 关闭:不转发数据,但照样收 BPDU —— 所以能顶上来
  • 结果必然无环,因为树的定义就是「边数 = 点数 − 1」

第 2 课 · ★★ 选根桥:最经典的事故就在这

入门 · 约 10 分钟

本课目标:搞清桥 ID 怎么比,以及为什么「不配优先级」会出事。

桥 ID = 优先级 + MAC

STP 的第一步是选出唯一的根桥,整棵树以它为中心长出来。

比的是桥 ID,8 个字节:

优先级(2 字节) + MAC 地址(6 字节)

规则很简单:整体当一个大数比,谁小谁赢 ——
也就是「先比优先级,优先级相同才比 MAC」。

★ 优先级默认 32768,而且必须是 4096 的倍数
(低 12 位后来被 System ID 扩展占了,用来支持每 VLAN 一棵树)。

★★★ 于是有了这个事故

如果全网都不配优先级,那么所有设备都是 32768 —— 优先级比不出胜负,
于是只能比第二项:MAC 地址。

而 MAC 地址通常和设备的出厂年份相关。

★★ 结果往往是:机房里最老、性能最差、位置最偏的那台接入交换机当了根桥 ——
而没有任何人做过这个决定。

⚠️ 后果很隐蔽,因为网络是通的:
· 所有跨交换机的流量都要绕到那台破设备上,绕出一大段不必要的路径
· 它的背板和 CPU 成了全网瓶颈
· 它一重启,全网重新收敛(几十秒业务中断)

★ 这是个典型的「监控全绿,就是慢」的问题 —— 不主动查根本发现不了。

动手:亲眼看到根桥落在破设备上

当前场景是 ② 根桥选错了:核心 + 汇聚 + 两台接入,全部默认优先级。

去根桥选举页,看「凭什么赢」那一段 ——
它会明确告诉你根桥是靠比 MAC 选出来的,而且赢的是那台 Acc1-老设备。

★ 然后切到 ③ 规划好的根桥 场景对比:同样的拓扑,
只是核心配了 4096、备核心 8192 —— 根桥立刻回到了该在的位置。

★ 现网的规范做法

主核心 4096、备核心 8192、接入层保持默认 32768。

这样做到三件事:
· 根桥唯一确定,不靠比 MAC 的运气
· 主核心挂了,根桥落到备核心(而不是随机跑到某台接入设备)
· 新加的接入设备永远抢不到根桥(默认值最大)

⚠️ 顺带一个坑:别把优先级配成 0。
配 0 之后想再插一台优先级更低的设备就没空间了 —— 留一档余量。

实验重点

  • 桥 ID = 优先级(2B) + MAC(6B),整体比大小,谁小谁赢
  • 优先级默认 32768,必须是 4096 的倍数
  • ★★★ 全默认 → 只能比 MAC → 最老的破设备当了根桥,而且没人做过这个决定
  • ★ 规范:主核心 4096、备核心 8192、接入层默认

第 3 课 · 端口角色:树是怎么长出来的

入门 · 约 10 分钟

本课目标:用两句话推出整棵树。

★ 总纲就两句话

① 每台非根交换机,有且只有一个根端口。
② 每条链路上,有且只有一个指定端口。

剩下的端口全部阻塞。就这么简单,整棵树是这两句话推出来的。

★ 为什么结果必然是树?因为每台非根设备恰好有一条朝上的边(根端口),
N 台设备 N−1 条边 —— 这正是树的定义。

根端口怎么选(三级比较)

根端口 = 朝着根桥的那个口。选法依次比,比出来就停:

① 到根的路径开销最小
② 开销相同 → 对端桥 ID 最小
③ 还相同 → 对端端口 ID 最小

★ 路径开销按链路速率取值(802.1D 短格式):
· 10M → 100 · 100M → 19 · 1G → 4 · 10G → 2

⚠️ 注意开销是累加的,而且加的是入端口的开销 ——
BPDU 每经过一条链路,接收方就把这条链路的开销加进去。

指定端口怎么选

指定端口 = 一条链路上负责往下游发 BPDU 的那一端。

选法:这条链路两端谁离根更近(路径开销更小),谁就是;
开销相同 → 桥 ID 更小的那端。

★ 两条有用的推论:
· 根桥的所有端口都是指定端口(它到根开销是 0,没人比它近)
· 如果一端是根端口,另一端必然是指定端口

动手:逐个端口看「为什么」

去端口角色页。表格里每个端口都有一列 「为什么是这个角色」 ——
它把上面那三级比较的具体数字写出来了。

★ 重点看那个阻塞端口:它既没竞争到根端口,在自己那条链路上也没竞争到指定端口。

实验重点

  • ★ 每台非根设备一个根端口;每条链路一个指定端口;其余全阻塞
  • 根端口三级比较:路径开销 → 对端桥 ID → 对端端口 ID
  • 指定端口:离根更近的那端,平局比桥 ID
  • 路径开销:10M=100 / 100M=19 / 1G=4 / 10G=2,累加

第 4 课 · ★★★ 收敛要多久:30 秒还是 50 秒

排障 · 约 12 分钟

本课目标:看清经典 STP 最致命的问题 —— 也是它被淘汰的直接原因。

四个端口状态,两个 15 秒

一个阻塞端口要变成能转发,必须依次走完:

Blocking → Listening(15 秒)→ Learning(15 秒)→ Forwarding

为什么要等?两个理由,都合理:
· Listening —— 等拓扑信息扩散完。不等就转发,可能出现「我以为我该转发、邻居也以为」的瞬时环路
· Learning —— 先安静地学 MAC 表。表空着就转发的话,头一批帧全得泛洪,冲击太大

★ 但合理不代表可以接受 —— 加起来就是 30 秒。

★★ 而间接故障还要再多 20 秒

关键区别在于这台设备知不知道出事了:

· 直接故障 —— 断的是自己的端口,物理层立刻报 down → 不用等,直接进状态机 → 30 秒
· 间接故障 —— 断的是别处的链路,它压根不知道。
只能靠「怎么好久没收到 BPDU 了」来推断,而这要等 MaxAge = 20 秒 → 总共 50 秒

⚠️ 那 20 秒是纯粹的浪费:故障早就发生了,但没人知道。

★★★ 50 秒意味着什么(不只是「慢一会儿」)

· TCP 连接大量超时重连 —— 默认重传退避早就超了
· 语音 / 视频会议全断,要重新加入
· 数据库连接池被打空,应用开始报错
· ★★ 集群误判节点故障 —— 心跳超时会触发一轮不必要的主备切换,而切换本身还要再花时间

★★★ 最要命的一点:故障本身可能只持续了 1 秒(链路抖一下就好了),
但 STP 的收敛让业务中断了 50 秒 ——
协议的恢复过程比故障本身伤害更大。

动手:把链路断一次,看计时

去收敛过程页,选一条正在转发的链路,点「开始仿真」。

★ 看那条时间线:每个阶段花多少秒、业务在哪几个阶段是断的。
★★ 然后把左上角的协议切成 RSTP,同样的链路再断一次 —— 对比那个数字。

实验重点

  • Blocking → Listening(15s) → Learning(15s) → Forwarding
  • ★ 直接故障 30 秒,间接故障 50 秒(多等 20 秒 MaxAge)
  • ★★★ 后果不只是慢:TCP 断连、语音视频全断、集群误判并触发主备切换
  • 最要命的是协议的恢复过程比故障本身伤害更大

第 5 课 · RSTP:把 50 秒变成 1 秒

进阶 · 约 10 分钟

本课目标:理解 RSTP 靠什么做到快速收敛 —— 以及为什么现网没理由再用经典 STP。

★★ 三个改进

① 提议 / 同意机制(Proposal / Agreement)
两台设备直接握手确认「我可以转发了吗」「可以」——
不再靠「等计时器到」。这是最核心的改进。

② 备用端口(Alternate Port)
★ RSTP 把阻塞角色细分了,提前算好替补:
根端口一挂,备用端口立刻升为根端口 —— 不需要重新计算。

③ 边缘端口(Edge Port)
接终端的口直接进转发,跳过 30 秒等待。
因为对面是 PC,不可能构成环路,没必要等。

★ 边缘端口必须配 BPDU 保护

边缘端口跳过了所有检查,所以它有个风险:

如果这个口上收到了 BPDU,说明有人在这里私接了交换机。

⚠️ 这是现网环路最常见的来源 —— 员工自己带了个小交换机、会议室串了个傻瓜交换机。
更糟的是:私接的设备如果 MAC 更小,还可能把根桥抢走,全网拓扑翻转。

★ 所以边缘端口一定要配 BPDU 保护:
收到 BPDU 就直接关掉这个端口,把风险挡在源头。

★★ 这两条命令是现网标配,属于「不配会出事」的那一类:
stp edged-port enable + stp bpdu-protection

动手:同一个故障,两种协议

去收敛过程页:
① 先用 STP 断一条链路,记下那个秒数
② 把协议切成 RSTP,断同一条链路

★ 对比这两个数字 —— 这就是升级 RSTP 的全部收益。

实验重点

  • RSTP 靠三件事:提议/同意握手、备用端口、边缘端口
  • 收敛从 30~50 秒降到 1 秒以内
  • ★ 边缘端口必须配 BPDU 保护 —— 私接交换机是环路最常见的来源
  • ★★ 现网没有任何理由再用经典 STP,这是纯收益

第 6 课 · ★★ STP 的代价,以及数据中心为什么抛弃了它

进阶 · 约 10 分钟

本课目标:看清 STP 的固有代价,以及现代架构给出的另一个答案。

★ 代价:一半带宽买了不能用

STP 破环的方式是阻塞,而被阻塞的链路平时一个字节都过不去。

一台双上行的接入交换机:接了两条 1G 上行,
STP 阻塞掉一条 → 实际可用上行只有 1G,不是 2G。

⚠️ 而钱是照花的:光模块、端口、布线、机位、电力,一样都没省。

★ 去端口角色页看那个「被阻塞的带宽」统计 —— 它把这件事量化了。

二层内部的缓解手段

· 链路聚合(Eth-Trunk / Port-Channel)
把多条线捆成一条逻辑链路,STP 只当它是一条 —— 于是两条线都能转发。★ 这是最常用的手段

· 堆叠 / M-LAG
让两台物理设备在 STP 看来是一台 —— 上行可以双活

★ 但注意这些都是绕开 STP,不是改进 STP。二层的根本约束没变:必须无环。

★★★ 数据中心的答案:换掉二层

现代数据中心(spine-leaf)的做法更彻底:不在这一层解决问题。

它把 fabric 内部做成 L3,然后用 ECMP:

| | STP(二层) | L3 + ECMP |
|---|---|---|
| 冗余链路 | 阻塞掉 | 全部转发 |
| 带宽利用 | 一半闲置 | 100% |
| 加带宽 | 加了也是阻塞 | 插一台 spine 就多一条路 |
| 收敛 | 秒级 | 毫秒级(路由协议)|

★ 代价是业务要的二层(虚机迁移、同网段)得靠 VXLAN 在 L3 上叠出来。

★★ 去数据中心 Spine-Leaf 模块的「架构对比」页看那个完整对比 ——那一页讲的正是这件事。

★ 最后分清 STP 和 SPF

这两个缩写差一个字母,但是完全不同的东西,而这个项目里两者都有:

| | STP | SPF |
|---|---|---|
| 全称 | Spanning Tree | Shortest Path First |
| 中文 | 生成树(最小生成树)| 最短路径优先(Dijkstra)|
| 层 | 二层 | 三层 |
| 算什么 | 一棵树 | 到每个目的地的最短路 |
| 冗余链路 | 阻塞 | 全可用(+ECMP 分担)|
| 谁用 | 交换机 | OSPF / IS-IS |

★ 想看 SPF 的实现,去 OSPF 或 IS-IS 模块。

实验重点

  • ★ STP 的固有代价:被阻塞的链路买了不能用
  • 二层缓解手段:链路聚合、堆叠 / M-LAG(都是绕开 STP,不是改进它)
  • ★★★ 数据中心的答案:换成 L3 + ECMP,所有链路全转发
  • ⚠️ STP ≠ SPF:一个是二层生成树(阻塞冗余),一个是三层最短路(全可用)
冀ICP备2026021556号-2|冀公网安备13068302000206号