交换机环路这个问题,凡是动手搭过中型以上局域网的人都躲不开。我刚接触网络设备调试那会儿,总觉得把线插上、地址配通就完事了,直到有一次在机房里把两台接入交换机用两根网线做了冗余互联,整个网段瞬间瘫掉,广播包像雪崩一样在几台设备之间来回弹,面板灯狂闪,抓包软件里全是重复帧。那次之后我才真正重视起生成树协议这套东西。这篇内容就围绕华为交换机在 eNSP 模拟环境下的 STP 配置与选路规则展开,把原理、配置、选路逻辑和踩坑经验一次讲透。它解决的核心问题是二层环路带来的广播风暴与 MAC 表震荡,适合刚入门网络工程、正在备考相关认证,或者需要在模拟器里复现企业网冗余拓扑的朋友参考。哪怕你之前只配过 VLAN 和静态路由,跟着走一遍也能把 STP 的选路逻辑摸清楚。
1. 整体设计思路与方案选型拆解
1.1 为什么二层网络必须有生成树
二层交换机的转发逻辑和三层设备有本质区别。三层路由靠 TTL 逐跳递减来防止包无限循环,而二层帧没有 TTL 字段,以太网帧头里根本没有“还能走几跳”这种信息。一旦网络里出现物理环路,广播帧、未知单播帧、组播帧就会沿着环路无限复制转发。举个直观的例子:两台交换机用两根线互联,主机 A 发出一个广播帧,交换机 1 从端口 1 收到后泛洪到端口 2,交换机 2 又从自己的端口 1 收到,再泛洪回交换机 1 的端口 2,如此往复。每绕一圈帧就多一份,带宽在几秒内被吃满,CPU 被中断打爆,这就是广播风暴。
生成树协议的本质,是在保留物理冗余链路的前提下,通过逻辑上阻塞某些端口,把有环的物理拓扑修剪成一棵无环的树。链路故障时,被阻塞的端口再重新激活,恢复连通性。这个“先逻辑断环、故障再补上”的思路,是二层冗余设计的基石。在 eNSP 里做实验,最大的好处是你可以随便造环、随便拔线,不用担心影响真实业务,观察端口状态迁移和选路结果非常直观。
1.2 STP、RSTP、MSTP 该怎么选
华为交换机支持的生成树协议主要有三代:STP(802.1D)、RSTP(802.1w)和 MSTP(802.1s)。在 eNSP 里做学习实验,我建议先用 STP 把选路规则吃透,再过渡到 RSTP 和 MSTP,因为 STP 的状态机和选举逻辑最完整,理解透了后面两个就是做减法和加扩展。
| 协议类型 | 收敛速度 | 端口状态 | 适用场景 | 学习建议 |
|---|---|---|---|---|
| STP | 慢,30-50秒 | 5种(阻塞/侦听/学习/转发/禁用) | 早期网络、教学实验 | 首选,理解选举逻辑 |
| RSTP | 快,秒级 | 3种(丢弃/学习/转发) | 现代企业接入层 | 掌握边缘端口概念 |
| MSTP | 快,秒级 | 同RSTP | 多VLAN负载分担 | 掌握实例与映射 |
选型上的经验是:纯学习选路规则,STP 的慢收敛反而帮你把每个状态看得清清楚楚;实际项目里接入层基本都用 RSTP 或 MSTP,因为 STP 那 30 秒的侦听学习时间对业务感知太明显了。eNSP 里默认开启的是 MSTP,做 STP 实验前必须手动把模式切过去,这一点后面会细说。
1.3 实验拓扑的设计考量
我设计的实验拓扑是这样的:三台交换机 SW1、SW2、SW3 组成三角形互联,SW1 作为核心,SW2 和 SW3 作为接入,另外在 SW1 和 SW2 之间、SW2 和 SW3 之间各接一台 PC 用于验证连通性。三角形拓扑是观察 STP 选路最经典的形状,因为它必然产生一个阻塞端口,你能清楚地看到根桥、根端口、指定端口、阻塞端口四种角色如何分配。
为什么不用更复杂的四台以上拓扑?因为三角拓扑已经能完整覆盖根桥选举、根路径开销比较、发送者桥 ID 比较、端口 ID 比较这四级选路规则,再加设备只会让选举过程变复杂,不利于初学者定位每一步的比较结果。等你把三角拓扑的选路结果能手工推算出来,再扩展到多台就是重复应用同样的规则而已。
2. 核心概念与选路规则深度解析
2.1 桥 ID、根桥与优先级的关系
STP 选举的第一步是选根桥。每台交换机都有一个桥 ID(Bridge ID),由 2 字节的优先级和 6 字节的 MAC 地址组成。优先级默认 32768,取值范围 0-65535,但必须是 4096 的倍数,也就是说合法值只有 0、4096、8192……61440 这些。桥 ID 比较时先比优先级,优先级相同再比 MAC,数值小的胜出成为根桥。
这里有个实操细节很多人忽略:华为交换机的优先级修改命令是stp priority,但如果你直接敲stp priority 100,设备会报错,因为 100 不是 4096 的倍数。正确做法是敲 4096 的整数倍,比如stp priority 4096。我见过有同学为了“让某台设备当根桥”随手配了个 1,结果命令被拒绝还以为是模拟器 bug。其实这是标准规定的步长,目的是留出足够的位给后续扩展。
根桥选举的优先级比较逻辑,用生活化的类比就是:先看谁的“级别数字”小(优先级低者优先,注意这里是数值小优先),级别一样再看谁的“身份证号”小(MAC 小者优先)。所以想让某台交换机稳定当根桥,最稳妥的做法是手动把它的优先级调低,而不是赌 MAC 地址大小,因为 MAC 是设备出厂固定的,你没法保证它一定最小。
2.2 根路径开销与端口角色判定
根桥选出来后,每台非根交换机要选出一个根端口(Root Port),也就是到达根桥路径开销最小的端口。路径开销和链路带宽相关,华为设备默认使用 802.1t 标准的长整型开销值,千兆链路开销是 20000,百兆是 200000,万兆是 2000。注意不同厂商、不同标准下这个值可能不一样,做跨厂商对接时要留意。
根端口选举的比较顺序是:先比根路径开销,开销小的胜出;开销相同比上游(也就是对端)的桥 ID,小的胜出;还相同比上游的端口 ID,小的胜出;最后比本端的端口 ID。这个四级比较是 STP 选路的核心,我在实验里会刻意构造开销相同的情况,让你看到后面几级比较是怎么起作用的。
每条链路上还要选一个指定端口(Designated Port),规则是这条链路上哪台交换机到根桥的开销更小,它的端口就是指定端口。根桥上的所有端口默认都是指定端口。既不是根端口也不是指定端口的,就进入阻塞状态。这里要强调一个容易混淆的点:阻塞端口不是“坏了”,它仍然在接收 BPDU,只是不转发业务数据,一旦拓扑变化它会参与重新计算。
2.3 BPDU 报文与计时器的配合
STP 靠 BPDU(桥协议数据单元)报文交换信息。配置 BPDU 每 2 秒由根桥发起、逐级下发,里面携带根桥 ID、根路径开销、发送者桥 ID、发送者端口 ID 等字段。非根交换机收到 BPDU 后,会把自己的信息和收到的比较,如果自己更优就不转发对端的,如果对端更优就更新自己的根桥信息并继续向下游转发。
三个关键计时器要记牢:Hello Time 默认 2 秒,是 BPDU 发送间隔;Max Age 默认 20 秒,是 BPDU 的最长存活时间,超过这个时间没收到新 BPDU 就认为链路故障;Forward Delay 默认 15 秒,是侦听和学习的停留时间。STP 从阻塞到转发要经历阻塞→侦听(15秒)→学习(15秒)→转发,加上故障检测的 Max Age,最坏情况收敛要 50 秒左右。这个数字在实际业务里是相当难受的,这也是 RSTP 要改进的地方。
注意:三个计时器的关系有约束条件,Hello Time 必须小于 Max Age 的一半,Forward Delay 也有取值范围限制。手动改计时器时如果违反约束,设备会拒绝配置。一般实验里不建议乱改,保持默认最稳。
3. eNSP 环境下的完整配置实操
3.1 拓扑搭建与基础准备
打开 eNSP,拖入三台 S5700 交换机,分别命名为 SW1、SW2、SW3,再拖两台 PC。连线方案:SW1 的 GE0/0/1 连 SW2 的 GE0/0/1,SW1 的 GE0/0/2 连 SW3 的 GE0/0/1,SW2 的 GE0/0/2 连 SW3 的 GE0/0/2,形成一个三角。PC1 接 SW2 的 GE0/0/3,PC2 接 SW3 的 GE0/0/3。启动所有设备,等待指示灯变绿。
基础配置先做一遍,主要是改主机名、配管理地址(可选)。这里我建议养成习惯:每台设备先system-view进系统视图,sysname改名字,这样后面看display stp输出时不会搞混是哪台设备。PC 的 IP 我配成 192.168.1.10 和 192.168.1.20,掩码 255.255.255.0,网关暂时不配,因为这是纯二层实验。
关键一步:华为交换机默认生成树模式是 MSTP,做 STP 实验必须切模式。命令是stp mode stp,三台都要敲。切完之后用display stp看输出,确认模式显示为 STP。我踩过的坑是只在一台设备上切了模式,结果三台设备跑不同协议,BPDU 交互出现异常,端口状态一直不稳定,排查了半天才发现是模式不一致。
# SW1 基础配置 system-view sysname SW1 stp mode stp stp enable # SW2 基础配置 system-view sysname SW2 stp mode stp stp enable # SW3 基础配置 system-view sysname SW3 stp mode stp stp enable3.2 根桥指定与优先级配置
默认情况下三台交换机会自动选根桥,谁优先级都是 32768,那就比 MAC,MAC 最小的当根桥。这个结果不可控,实验里我们手动指定 SW1 为根桥,方便观察。命令是stp priority 4096,注意必须是 4096 的倍数。配完在 SW1 上display stp看CIST Root/ERPC字段,应该显示自己是根桥。
这里补充一个更省事的做法:华为有stp root primary和stp root secondary命令,直接指定主根和备根,设备会自动把优先级调到 0 和 4096。但要注意stp root primary会把优先级设成 0,这个值在标准里是保留的极端值,有些跨厂商场景下可能引起兼容性讨论,纯华为环境没问题。我实验里为了看清优先级数值变化,还是用stp priority 4096手动配,这样display stp里能明确看到 4096 这个值。
# SW1 指定为主根桥 system-view stp priority 4096 # 验证根桥身份 display stp # 关注输出中的 CIST Root/ERPC 和 CIST Bridge 字段配完根桥后,SW2 和 SW3 保持默认 32768。此时选路结果应该是:SW1 是根桥,SW2 和 SW3 各有一个根端口指向 SW1,SW2 和 SW3 之间的链路会有一个端口被阻塞。具体阻塞哪个,取决于端口 ID 比较,这个我们下一节详细推。
3.3 端口开销调整与选路干预
有时候默认选路结果不符合我们的流量规划,比如希望某条链路作为备份而不是主用,这时候就要手动调端口开销。命令是在接口视图下stp cost 数值。假设我们想让 SW2 到 SW3 的链路成为备份,可以调大相关端口开销,让 STP 优先走 SW1 中转。
调开销的实操要点:先想清楚你要改变的是哪一段的路径开销,再决定调哪个端口。因为根路径开销是累加的,你调 SW2 上行口和调 SW3 上行口,影响的路径不一样。我一般先在纸上画出当前选路结果,标出每条路径的累计开销,再决定动哪个端口。盲目调开销很容易把原本正常的阻塞端口搞到另一条链路上,结果和预期相反。
# 在 SW2 的 GE0/0/2 接口上调大开销,使其倾向阻塞 interface GigabitEthernet0/0/2 stp cost 200000 quit # 查看端口开销和状态 display stp interface GigabitEthernet0/0/2调完开销后,用display stp brief看所有端口角色和状态,这是最常用的排障命令,输出简洁,一眼能看出哪个端口是 ROOT、哪个是 DESI、哪个是 ALTE(阻塞)。
3.4 验证连通性与故障切换
配置完成后,从 PC1 ping PC2,应该能通。然后做故障切换实验:在 SW1 上把连接 SW2 的 GE0/0/1 口 shutdown,观察 STP 重新收敛。用display stp brief反复看,能看到原本阻塞的端口经过侦听、学习后变成转发,PC1 到 PC2 的 ping 在短暂中断后恢复。
这个实验的价值在于让你直观感受 STP 的收敛时间。STP 模式下,端口从阻塞到转发要经历 30 秒左右(侦听 15 秒加学习 15 秒),ping 会丢十几个包。如果你把模式切成 RSTP 再做同样的实验,恢复时间会短很多。这个对比做一次,你对两种协议的差异就有体感了,比看多少文字描述都管用。
4. 选路结果手工推演与验证对照
4.1 三角拓扑的完整选举推演
假设 SW1 优先级 4096,SW2、SW3 默认 32768,MAC 地址假设 SW1 < SW2 < SW3(实际以设备为准,这里为推演方便设定)。第一步选根桥:SW1 优先级最小,直接当选,不用比 MAC。
第二步选根端口。SW2 有两条路到根桥:经 GE0/0/1 直连 SW1,开销 20000;经 GE0/0/2 到 SW3 再到 SW1,开销 40000。显然直连路径开销小,SW2 的 GE0/0/1 成为根端口。同理 SW3 的 GE0/0/1 直连 SW1,开销 20000,成为根端口。
第三步选指定端口。SW1 的两个端口都是指定端口(根桥所有端口都是指定端口)。SW2 和 SW3 之间的链路,比较两端到根桥的开销:SW2 的 GE0/0/2 到根桥开销是 20000(经 GE0/0/1),SW3 的 GE0/0/2 到根桥开销也是 20000(经 GE0/0/1),开销相同,比发送者桥 ID,SW2 的桥 ID 小于 SW3,所以 SW2 的 GE0/0/2 成为指定端口,SW3 的 GE0/0/2 被阻塞。
这个推演过程建议你亲手在纸上画一遍,把每步比较的字段写出来。我当初学的时候就是靠反复手推,才把“为什么是这个端口阻塞”彻底搞明白。光看display stp的结果不推过程,换个拓扑又不会了。
4.2 display stp 输出字段逐行解读
display stp的完整输出信息量很大,初学者容易看晕。我挑几个关键字段说:CIST Root/ERPC显示根桥 ID 和到根桥的开销,如果这台是根桥,这里显示自己的桥 ID 且开销为 0;CIST Bridge是本设备的桥 ID;CIST Ports下面逐个端口列出角色、状态、开销、优先级。端口角色里 ROOT 是根端口,DESI 是指定端口,ALTE 是阻塞(替代)端口。
display stp brief是精简版,输出格式是端口、角色、状态、保护类型几列。排障时我基本只用这个,因为信息足够且一眼能扫完。比如看到某个端口角色是 ALTE、状态是 DISCARDING,就知道它被阻塞了,符合预期。
| 字段 | 含义 | 排障关注点 |
|---|---|---|
| CIST Root/ERPC | 根桥ID/到根桥开销 | 确认根桥是否正确 |
| CIST Bridge | 本机桥ID | 确认优先级和MAC |
| Port Role | 端口角色 | ROOT/DESI/ALTE |
| Port State | 端口状态 | 转发/阻塞/学习 |
| Port Cost | 端口开销 | 是否被手动修改 |
| Port Priority | 端口优先级 | 同级比较时用 |
4.3 端口 ID 比较的边界情况
前面推演里 SW2 和 SW3 之间靠桥 ID 分出了胜负,但如果两台交换机的桥 ID 也相同呢?理论上桥 ID 包含 MAC,不会完全相同,但端口 ID 比较确实会在某些场景下成为决胜因素。端口 ID 由 1 字节端口优先级(默认 128)和 1 字节端口号组成,比较时先比优先级再比端口号。
构造一个场景:如果 SW2 和 SW3 的桥 ID 恰好相同(实际不会,但推演时可以假设),那么 SW2 的 GE0/0/2 和 SW3 的 GE0/0/2 就比较端口 ID。假设端口优先级都是 128,那就比端口号,GE0/0/2 的端口号是 2,如果对端是 GE0/0/3 端口号 3,则端口号小的胜出成为指定端口。这个细节在复杂拓扑里会用到,尤其是你想通过调端口优先级来干预选路时。
调端口优先级的命令是接口下stp port priority 数值,数值必须是 16 的倍数,范围 0-240。这个和桥优先级必须是 4096 倍数是一个道理,都是标准规定的步长。我一般不建议轻易动端口优先级,因为它的影响范围比端口开销小,容易和其他配置叠加出意外结果,除非你明确知道自己在干什么。
5. 常见问题排查与避坑经验实录
5.1 端口状态一直卡在侦听或学习
这是 STP 实验里最高频的问题。端口长时间停在 LISTENING 或 LEARNING 不往 FORWARDING 走,通常有几个原因。第一是拓扑里存在持续的 BPDU 冲突,比如有设备在不停地发更优的 BPDU,导致选举反复。第二是计时器被改乱了,Forward Delay 设得过大。第三是物理链路不稳定,eNSP 里偶尔会出现链路状态抖动,导致 BPDU 收发异常。
排查思路:先display stp brief看端口状态,再display stp interface 端口号看该端口的详细 BPDU 统计,重点看收到和发送的 BPDU 计数是否在增长。如果收到的 BPDU 一直在变,说明上游选举不稳定;如果根本没收到 BPDU,检查链路和模式是否一致。我在 eNSP 里遇到过一次,原因是三台设备里有一台忘了切 STP 模式,还在跑 MSTP,BPDU 格式对不上,端口就一直卡着。
5.2 根桥不是预期的设备
明明配了优先级,根桥却不是自己。先检查优先级是不是 4096 的倍数,配错了命令会被拒绝但很多人没注意回显。再检查是不是所有设备都参与了选举,有没有设备配了stp priority 0这种更极端的值。还有一种情况是设备刚启动,STP 还在收敛中,display stp显示的是临时结果,等几十秒再看就对了。
提示:改完优先级后,STP 不会立刻重新选举,要等下一次 BPDU 交互或者手动触发。急的话可以在设备上
reset stp重置一下,或者干脆等一个 Hello 周期。实验里我一般改完等 30 秒再验证,避免看到中间态误判。
5.3 故障切换后业务恢复慢
STP 模式下这是正常现象,30 秒的收敛时间摆在那。如果你觉得慢,说明你该上 RSTP 了。但要注意,切 RSTP 不是简单改个模式就完事,边缘端口(连接终端的端口)要配stp edged-port enable,否则终端插拔还是会触发拓扑计算。另外 RSTP 的快速收敛依赖邻居协商,如果对端不支持 RSTP,会退化成 STP 行为。
| 问题现象 | 可能原因 | 排查命令 | 解决方向 |
|---|---|---|---|
| 端口卡侦听/学习 | 模式不一致/BPDU冲突 | display stp interface | 统一模式,检查链路 |
| 根桥不符预期 | 优先级非4096倍数 | display stp | 重配优先级 |
| 切换慢 | STP固有收敛时间 | display stp brief | 升级RSTP/MSTP |
| 端口不阻塞 | 开销配置相反 | display stp interface | 核对开销值 |
| 终端插拔引发震荡 | 未配边缘端口 | display stp brief | 配edged-port |
5.4 eNSP 模拟器的特有坑
eNSP 毕竟是模拟器,有些行为和真机有差异。我遇到过几个典型情况:一是设备启动后 STP 收敛比真机慢,display stp刚启动时输出可能不完整,多等一会儿再查;二是链路断开后模拟器的状态更新有延迟,做故障切换实验时 ping 的丢包数和真机不完全一致,别拿模拟器的收敛时间当精确指标;三是某些低版本 eNSP 里 S5700 的 STP 命令回显和真机略有出入,以display stp实际输出为准。
还有一个经验:eNSP 里做 STP 实验,建议把每台设备的配置保存一下(save),因为模拟器偶尔会崩,重开之后配置丢了又得重来。尤其是拓扑复杂的时候,重配一遍很浪费时间。我现在的习惯是每完成一个阶段就保存,命名带上阶段号,方便回退对比。
6. 从 STP 到 RSTP 的平滑过渡实践
6.1 模式切换的注意事项
把stp mode stp改成stp mode rstp,三台设备都要改,而且最好在业务低峰或者实验环境里做,因为切换瞬间会有短暂的收敛过程。切完之后display stp里的状态会从 5 种变成 3 种(DISCARDING、LEARNING、FORWARDING),端口角色名称也有变化,比如 ALTE 在 RSTP 里叫 ALTERNATE,含义类似但机制不同。
切换时的一个关键点:RSTP 的快速收敛依赖端口之间的 Proposal/Agreement 握手,这个握手要求链路两端都运行 RSTP。如果拓扑里混了一台只支持 STP 的老设备,那段链路会退化成 STP 的慢收敛,但其他 RSTP 链路仍然快。所以做混合组网时,要清楚哪段是快收敛、哪段是慢收敛,别以为全局切了 RSTP 就处处都快。
6.2 边缘端口配置与终端接入优化
连接 PC 的端口一定要配边缘端口。命令是接口下stp edged-port enable。配了之后,这个端口一上来就直接进转发状态,不参与 STP 计算,终端插拔也不会触发拓扑变更。这是 RSTP 相比 STP 最实用的改进之一,接入层交换机上几乎每个连终端的端口都该这么配。
但边缘端口有个风险:如果这个端口不小心接到了另一台交换机上,而对方也在发 BPDU,就可能引起环路。华为设备有 BPDU 保护机制,配stp bpdu-protection后,边缘端口一旦收到 BPDU 就会自动 shutdown,防止误接。这个保护在实际项目里强烈建议开,实验里也值得演示一遍,让你看到端口被保护性关闭的效果和恢复方法(手动 undo shutdown 或者配自动恢复)。
# 在连接PC的接口上配置边缘端口和BPDU保护 interface GigabitEthernet0/0/3 stp edged-port enable quit stp bpdu-protection # 查看边缘端口状态 display stp interface GigabitEthernet0/0/36.3 收敛速度对比实测
在同样的三角拓扑上,我做过 STP 和 RSTP 的切换对比。STP 模式下拔掉 SW1 到 SW2 的线,PC1 到 PC2 的 ping 中断大约 30 秒后恢复,丢包 30 个左右。切到 RSTP 并配好边缘端口后,同样的操作,中断时间缩短到 1-2 秒,丢包 2-3 个。这个差距在真实业务里就是“用户几乎无感”和“用户打电话投诉”的区别。
不过要客观说,RSTP 的快速收敛在复杂拓扑里也不是万能的,它依赖备份端口的预计算和握手协商,如果拓扑变化点离根桥很远,收敛时间还是会拉长。MSTP 在此基础上又加了多实例负载分担,适合多 VLAN 环境。学习路径上,我建议先把 STP 的选路规则彻底吃透,再理解 RSTP 的状态精简和握手机制,最后看 MSTP 的实例映射,这样每一步都有落脚点,不会觉得概念悬空。
7. 我个人在实际操作中的几点体会
做 STP 实验最忌讳的就是只看结果不推过程。display stp brief告诉你哪个端口阻塞,但为什么是它阻塞,你得能自己推出来。我的习惯是每次配完先不看命令输出,自己在纸上把根桥、根端口、指定端口、阻塞端口全推一遍,再拿输出对照,对不上就找原因。这个笨办法坚持一段时间,选路规则就刻在脑子里了。
另一个体会是关于实验记录的。eNSP 里做实验很方便,但也容易做完就忘。我现在每个 STP 实验都会截几张关键图:拓扑图、display stp输出、ping 结果,配上几句配置说明存到一个文档里。过段时间回头看,比翻命令历史高效得多。尤其是选路结果和预期不符的时候,这些记录能帮你快速定位是配置问题还是理解偏差。
最后分享一个小技巧:想快速验证某条链路的阻塞是否符合预期,不用反复 ping,直接在两端交换机上display stp brief对比端口角色就行。如果一端是 DESI 一端是 ALTE,说明这条链路正常阻塞;如果两端都是 DESI,那就有问题了,可能是链路两端不在同一个 STP 域或者模式不一致。这个检查方法比抓包快,适合日常巡检。