1. 单生成树在多网段场景下的三个硬伤
先说一个我见过太多次的场景:实验环境里搭了三台交换机,接了两个业务网段,VLAN 10 和 VLAN 20。所有人第一反应都是"开个 STP 不就行了",敲完stp enable,网络确实通了,也没有环路风暴,看起来一切正常。可真要问一句"VLAN 20 的流量现在走哪条链路",大部分人答不上来——因为 STP 压根不关心你是哪个 VLAN,它只认整张二层拓扑,所有 VLAN 共用同一棵生成树、同一个根桥、同一个阻塞口。
这就是 MSTP(Multiple Spanning Tree Protocol,多生成树协议)要解决的原点问题。它不是把一个 STP 做得更快,而是把"一棵树"变成"多棵树",让不同的 VLAN 走不同的路径。eNSP 里敲几条命令就能看到效果,但要真正把 MSTP 用明白,得先搞清楚单生成树到底卡在哪。下面这三条,是我认为最需要在动手前想清楚的地方。
1.1 VLAN 数量上去了,链路却一直闲着
三层交换机做汇聚,典型接法是两台汇聚、多台接入,接入到汇聚做双上行。STP 一开,双上行里必然有一条被阻塞——注意,是"一条链路"被阻塞,而不是"某个 VLAN 的一条链路"。假设你有 VLAN 10 到 VLAN 50 共 41 个业务网段,全部跑在这一对上行链路上,那么被阻塞的那条链路对全部 41 个 VLAN 来说都是死的。
结果就是:一条上行 100% 承载,另一条 0% 承载,永远在待机。很多人以为这是"冗余的代价",其实不是。真正的冗余是可以既备份又分担的,只是 STP 这种单实例模型做不到。MSTP 把 VLAN 10 绑到实例 1、VLAN 20 绑到实例 2,实例 1 的树和实例 2 的树各算各的,阻塞口的位置就可以不同,两条上行同时跑流量。这是最直观的价值,也是绝大多数人学 MSTP 的第一动因。
我在实验里做过对比:同样的三角拓扑,STP 模式下两条汇聚链路的流量比大约是 100:0,改成两个 MSTP 实例后变成 60:40 左右——为什么不是 50:50,后面讲端口开销和路径选择时会解释,这跟链路带宽是否对等有关。
1.2 STP 和 RSTP 的阻塞口位置,你说了不算
STP 选路只依赖三个参数:根桥 ID、根路径开销、发送者端口 ID(再往后是接收端口 ID)。你能干预的只有优先级和端口开销,而且这个干预是全 VLAN 生效的。想让 VLAN 10 走左边、VLAN 20 走右边,在单实例模型里根本没有对应的旋钮。
有人会想到调端口开销,但在单实例下,你把左边路径开销调小,所有 VLAN 全走左边;调大,所有 VLAN 全走右边。无论怎么调,都只能得到"一条路全通、另一条全堵"的结果。这是模型层面的限制,不是配置技巧能绕过去的。
MSTP 的旋钮就多了:每个实例可以单独设根桥优先级,每个实例可以单独设端口开销和端口优先级。换句话说,你可以给实例 1 指定甲设备当根,给实例 2 指定乙设备当根,两张树自然就长成不同形状。这也是实验里最值得反复练的部分——不是记住命令,而是能从display stp instance的输出里预判出阻塞口会在哪。
1.3 二层环路和广播风暴的真实代价
实验室里环路风暴顶多让 eNSP 卡一下,现网里几分钟就能把一台接入交换机打死。二层没有 TTL,广播帧、未知单播帧、组播帧在环里会无限复制,CPU 和上行带宽瞬间打满,连管理面都可能被冲垮,最后只能去机房拔线。
所以生成树不是"可选优化",是二层网络的保命机制。而 MSTP 在保留这套保命机制的前提下,额外给了你按 VLAN 分配路径的能力。这里面有个容易忽视的前提:MSTP 掌管的只是无环这件事,它不管你三层通不通、VRRP 主备是谁、网关在哪。经常有人配完 MSTP 发现某个 VLAN 不通,第一反应是生成树配错了,其实生成树只负责"别成环",通不通是 VLAN 放行、接口类型、网关这些另一套事情。这个边界必须先划清楚,否则排障会走很多弯路。
2. 把"域"和"实例"这两个词掰开揉碎
MSTP 的概念比 STP 多不少,域、实例、CIST、IST、总根、域边缘端口,一堆词砸下来很容易懵。我的经验是:别按文档顺序背,先抓住一条主线——MSTP 是两层结构,域内一张总图,域外一张总图,实例只在域内有意义。理解这句话,剩下的名词都能挂上去。
2.1 域(Region):三要素一模一样才算同一家人
MSTP 域是一组交换机的逻辑集合,只有配置完全一致的三样东西,它们才属于同一个域:
| 要素 | 命令 | 说明 |
|---|---|---|
| 域名 | region-name | 自定义字符串,缺省是设备 MAC 地址 |
| 修订级别 | revision-level | 0~65535 的整数,缺省 0 |
| VLAN 与实例映射 | instance N vlan ... | 决定哪个 VLAN 归哪个实例 |
这三样合起来会算出一个配置摘要(配置标识),随 MST BPDU 一起发出去。邻居收到后一比对,摘要对得上才认为同域,对不上就当你是外域设备。这里最容易踩的坑是:只改了域名没改修订级别,或者两边 VLAN 映射顺序不同,摘要照样对不上。
注意:修订级别不是"版本号越大越优先",它纯粹是标识的一部分。两台设备一个写 1 一个写 0,即使域名一样,也是两个域。我在实验里吃过这个亏,排查了半小时才发现是抄配置时漏了一行。
为什么要有"域"这个概念?因为 MSTP 要在整个网络里保证无环,而不同管理员可能各自规划实例。如果没有任何边界约束,A 区的实例 1 和 B 区的实例 1 混在一起算,语义就乱了。域的存在让每个管理域内部自成体系。
2.2 实例与 VLAN 的映射:一对多,不是一对一
一个实例可以映射多个 VLAN,一个 VLAN 只能映射到一个实例。这个方向性一定要记牢:instance 1 vlan 10 30 50是合法的,把 VLAN 10 同时写进实例 1 和实例 2 是不合法的,设备会直接报错。
映射关系决定了哪些 VLAN 共用一棵树。规划的时候要考虑流量模型:访问关系密切、流量方向一致的 VLAN 放同一个实例,能减少实例数量、降低设备计算开销;流量需要走不同路径的 VLAN,必须拆到不同实例。
另外,没有显式映射的 VLAN 默认都归实例 0。实例 0 是特殊的,它对应 CIST,是所有实例的"底座",不能删除也不能取消映射关系,你只能往里加 VLAN。这一点新手常忽略:配完实例 1 和实例 2 之后,剩下没管的 VLAN 全在实例 0 里,而实例 0 的树又是全网统一算的,所以实例 0 的规划同样重要。
2.3 CIST、IST、总根:域内域外两张图怎么拼起来
这几个缩写最容易绕晕,用一句话概括:IST 是域内的那棵树,CST 是域间的那棵树,CIST 是把两者拼起来的整棵大树。
- IST(Internal Spanning Tree):域内所有交换机在实例 0 上算出来的树,只在本域内有效。
- CST(Common Spanning Tree):把每个域压缩成一台虚拟设备,域与域之间算出来的树。对于外域设备来说,你这个域就是一台机器。
- CIST(Common and Internal Spanning Tree):IST 加 CST,全网唯一一棵总树,它的根叫总根。
总根的选举规则是:先比 CIST 优先级(就是实例 0 的优先级),再比 MAC。所以想让某台设备当总根,本质上就是把它实例 0 的优先级调到最小。工程上一般把两台核心之一设为总根,另一台设为备份总根,接入层不参与。
还有一个词叫域边缘端口,指连接到其他域或者单生成树设备的端口。MSTP 在域边缘端口上要做 MST BPDU 到普通 STP BPDU 的转换,这部分行为在纯单域环境里看不到,一旦网络里有老设备或者别的厂商设备就会冒出来,属于排障时的隐藏考点。
2.4 端口角色和状态:MSTP 比 RSTP 多出来的那几个
状态层面 MSTP 和 RSTP 一样,只有三种:Discarding、Learning、Forwarding。比 STP 的五种状态(Disabled、Blocking、Listening、Learning、Forwarding)精简了,因为 RSTP/MSTP 把"不转发"的几种情况统一归到 Discarding。
角色层面比 RSTP 多一个概念:
| 角色 | 含义 |
|---|---|
| 根端口(Root) | 到本实例根桥开销最小的口 |
| 指定端口(Designated) | 某网段上负责向该网段转发的最优口 |
| 替代端口(Alternate) | 从别的交换机收到的更优 BPDU,作为根口的备份 |
| 备份端口(Backup) | 从本机其他口收到的更优 BPDU,作为指定口的备份,自环场景才出现 |
| 边缘端口(Edge) | 手工指定,接终端,不参与生成树计算,up 即转发 |
| Master 端口 | 域边缘端口在 CIST 上充当根口或指定口时的角色 |
实际排障时看display stp brief,重点盯两列:STP State和Port Role。看到某个口是ALTE且状态DISCARDING,就说明它被选为备份路径了,这时候要去确认这是不是你想要的结果——是,就说明负载分担生效了;不是,就去查实例根桥优先级。
3. eNSP 里把实验环境搭起来
理论说再多,不如敲一遍。我建议的拓扑是经典三角加接入,三台交换机足够看清全部现象,多了反而乱。下面这套配置我反复用过,可以直接照着敲。
3.1 拓扑与规划
SW1(核心A)======== SW2(核心B) || || || || ======== SW3 ======== | PC1(VLAN10) / PC2(VLAN20)连接关系:
| 链路 | 一端 | 另一端 | 说明 |
|---|---|---|---|
| L1 | SW1 GE0/0/1 | SW2 GE0/0/1 | 核心互联 |
| L2 | SW1 GE0/0/2 | SW3 GE0/0/1 | 汇聚-接入 |
| L3 | SW2 GE0/0/2 | SW3 GE0/0/2 | 汇聚-接入 |
| L4 | SW3 GE0/0/3 | PC1 | 接 VLAN10 终端 |
| L5 | SW3 GE0/0/4 | PC2 | 接 VLAN20 终端 |
规划要点:
| 项目 | 规划 |
|---|---|
| 实例 0(CIST) | 不放业务 VLAN,只做总根选举 |
| 实例 1 | VLAN 10,根桥 SW1,备份 SW2 |
| 实例 2 | VLAN 20,根桥 SW2,备份 SW1 |
| 域名 | RG-CORE |
| 修订级别 | 1 |
为什么不把业务 VLAN 放进实例 0?因为实例 0 的树是全 CIST 共用的,一旦某个 VLAN 放进去,它的路径就绑死在总根身上,丧失灵活性。惯例做法是实例 0 只承担"总根锚点"的角色,业务流量全部下放到 MSTI 里。
3.2 设备选择与 eNSP 的脾气
eNSP 里拉 S5700 就够了,三层特性齐全,MSTP 命令完整。有几个地方必须提前知道,否则会浪费大量时间:
启动慢。三台交换机加两台 PC,点启动后要等指示灯全绿,端口才会 up。急着敲display stp brief看到全是 DISCARDING,先别慌,等 30 秒再说。
PC 的配置。eNSP 的 PC 需要手工配 IP 和掩码,别忘了配网关。测跨 VLAN 通不通,网关必须指向对应 VLANIF 地址。
抓包。eNSP 支持在链路上抓包,MSTP 的 BPDU 目的 MAC 是01-80-C2-00-00-00,在 Wireshark 里过滤stp就能看到,协议版本显示 MSTP 或者 RSTP(版本 3 就是 MSTP)。看 BPDU 内容是理解域参数最直接的方式。
保存与回滚。eNSP 的配置保存在工程里,建议每一步验证通过后再继续下一步,别一口气敲完再测,出了问题找不到是哪一步引入的。
3.3 域配置的固定套路
三台交换机的域配置必须一字不差,我习惯按固定顺序敲,避免漏项:
system-view sysname SW1 vlan batch 10 20 stp mode mstp stp region-configuration region-name RG-CORE revision-level 1 instance 1 vlan 10 instance 2 vlan 20 active region-configuration quit顺序为什么重要?因为active region-configuration之前的所有修改都是"待生效"状态,设备仍然用旧参数跑。很多人配完域参数不敲这一行,然后display stp region-configuration看到的还是默认值,怎么排查都找不到原因。
提示:
active命令会让本设备的域参数立即生效,可能引起短暂的拓扑震荡。现网操作建议在业务低峰期做,或者提前把相关端口 shutdown。
三台设备敲完后,一定要在三台上都执行display stp region-configuration,逐行对比输出。重点看三栏:Region Name、Revision Level、Instance Vlans Mapped。三台完全一致,才算配好了域。
3.4 主备根桥:priority 和 root primary 的区别
指定根桥有两种写法,效果相近但含义不同:
stp instance 1 priority 0或者
stp instance 1 root primarypriority是直接设值,取值必须是 4096 的整数倍(0、4096、8192……61440),数值越小优先级越高。root primary是让设备"自动算一个足够小的值",通常是 0。备份根用root secondary,实际会设成 4096。
什么时候用哪个?我自己的习惯是:明确知道要抢根的设备,直接写priority 0,一眼能看出意图;不确定网络里还有没有别的设备在抢根,用root primary让设备自己去算更保险。但要注意,root primary并不是"永远第一",如果网络里已经有另一台设备优先级也是 0,那就比 MAC,MAC 小的赢。所以在现网里,核心层两台设备的优先级不要都设 0,一台 0 一台 4096,结果才是确定的。
SW1、SW2、SW3 的完整规划:
| 设备 | 实例 0 | 实例 1 | 实例 2 |
|---|---|---|---|
| SW1 | 主根(0) | 主根(0) | 备份(4096) |
| SW2 | 备份(4096) | 备份(4096) | 主根(0) |
| SW3 | 不设 | 不设 | 不设 |
接入层 SW3 永远不参与抢根,保持默认 32768 就行。
4. 让两个实例真的跑出两条路径
域配好了、根桥定好了,接下来是端口层面的事。这部分看似简单,实际上大部分"配了不通"的问题都出在这里。
4.1 Trunk 口放行与端口类型
所有互联口都要配成 Trunk 并放行相关 VLAN:
interface GigabitEthernet 0/0/1 port link-type trunk port trunk allow-pass vlan 10 20 quitSW1、SW2、SW3 之间六条链路端口全部照此处理。这里有个高频问题:只放行了 VLAN 10 忘了 VLAN 20,结果实例 2 对应的业务不通,但生成树计算看起来完全正常——因为 MSTP 算树看的是实例关系,和 VLAN 在接口上放不放行是两回事。所以"树是好的但业务不通",第一个要查的就是 allow-pass。
接入 PC 的口配 Access 加边缘端口:
interface GigabitEthernet 0/0/3 port link-type access port default vlan 10 stp edged-port enable quit interface GigabitEthernet 0/0/4 port link-type access port default vlan 20 stp edged-port enable quit边缘端口的作用是不参与生成树计算、链路 up 后直接进 Forwarding,省掉 30 秒左右的收敛时间。接终端的口必须开,不然用户每次插网线要等半分钟才能上网。反过来,接交换机的口绝对不能开边缘端口,一开就可能成环,因为边缘端口不处理 BPDU,收到也直接丢,环路检测机制直接失效。这条规矩我贴在实验室墙上:不确定对面是什么,就别开。
4.2 端口开销:为什么不是 50:50
MSTP 选路的核心是根路径开销,华为默认使用dot1t标准(IEEE 802.1t),千兆口开销是 20000,百兆口是 200000。eNSP 里默认链路是千兆,所以 SW3 到 SW1、SW3 到 SW2 的开销一样,理论上应该 50:50 分担。
实际测下来往往有偏差,原因主要有两个:一是实际转发的 VLAN 数量和流量大小不对等,本来就不是均分;二是路径上经过的跳数不同,比如 VLAN 10 走 SW3-SW1 两跳,VLAN 20 走 SW3-SW2-SW1 三跳,开销自然不同。
想人为干预路径,有两个旋钮:
interface GigabitEthernet 0/0/1 stp instance 1 cost 20000 stp instance 1 port priority 16 quitcost是端口开销,port priority是端口优先级(取值 0~240,步长 16)。优先级只在开销相同时才起作用,用来打破平局。经验是:能用改实例根桥解决的,就不要去改端口开销。改根桥是全局性的、可读性强的;改开销是局部的,配置多了以后很难维护,一两年后接手的人根本看不懂为什么这个口是 20000。
有个细节值得注意:stp pathcost-standard有三个取值,dot1d-1998、dot1t、legacy。华为设备默认dot1t,但如果网络里有老设备用的是 802.1D 的计算方式,两边开销数值不在一个量级,算出来的路径会非常诡异。混合组网时,全网统一成本标准是第一步要做的事,比调任何参数都重要。
4.3 用 display 命令验证阻塞口落在哪
配置完了,别急着 ping,先看拓扑:
display stp brief输出里会列出每个端口在实例 0、1、2 下的角色和状态。重点关注MSTID这一列,0 是 CIST,1 和 2 是实例。SW3 上应该能看到类似这样的结果:
| 端口 | MSTID | 角色 | 状态 |
|---|---|---|---|
| GE0/0/1 | 1 | ROOT | FORWARDING |
| GE0/0/1 | 2 | ALTE | DISCARDING |
| GE0/0/2 | 1 | ALTE | DISCARDING |
| GE0/0/2 | 2 | ROOT | FORWARDING |
这就是最理想的结果:同一个物理口 GE0/0/1 在实例 1 上转发、在实例 2 上阻塞,GE0/0/2 正好反过来。两条上行同时被使用,各自承载一个实例的流量。
想看更细的信息,用:
display stp instance 1 display stp interface GigabitEthernet 0/0/1前者看实例 1 的根桥是谁、本机到根的开销多少、根端口是哪个;后者看某个口的详细收发计数,BPDU 收发了多少个、有没有错误包。排障时这两个命令配合使用,基本能定位 80% 的问题。
还有一个容易被忽视的命令:
display stp topology-change它会显示拓扑变化次数。如果这个数字一直在涨,说明网络里有端口反复 up/down,可能是线路问题,也可能是某个口没配边缘端口导致接终端时抖动。这个指标比看端口状态更早发现问题。
4.4 拔线看收敛:MSTP 到底快不快
验证完静态拓扑,一定要做破坏性测试。在 eNSP 里直接删掉 SW3 到 SW1 的链路,或者 shutdown 端口,然后观察:
- 实例 1 的流量在 1 秒内切换到 SW3-SW2-SW1 路径;
- 实例 2 的树基本不动,因为它的根端口本来就在另一边;
- 拓扑变化计数增加,但很快稳定。
这里能体现出 MSTP 相比 STP 的优势。STP 收敛要经历 Listening 和 Learning 各 15 秒,30 秒起步;MSTP 基于 RSTP 的 P/A 机制(Proposal/Agreement),在点对点链路上可以做到秒级甚至亚秒级收敛。但有个前提:链路必须是全双工点对点。如果端口是半双工,或者对端是共享介质(比如接了个 Hub),P/A 机制会退化成传统的等待计时器,收敛时间立刻回到 30 秒。
判断端口是不是点对点,看display stp interface输出里的Port STP Mode和Cost附近的信息,华为设备一般会标注端口的工作模式和双工状态。实验里如果发现收敛慢得离谱,先查双工。
5. 保护特性:让 MSTP 不被意外事件打趴
生成树本身是健壮的,但它假设所有设备都守规矩。现实是:有人把网线插错口、有人把家用路由器接到墙上、有人把上级交换机的配置改错。这些意外会直接把生成树带崩。保护特性就是给这些场景兜底的。
5.1 边缘端口 + BPDU 保护:接终端的口被接了交换机
最经典的故障:某工位把墙上的网线插到了一个自己带的小交换机上,小交换机又接回另一个墙口,二层环路形成;或者有人把公司另一台交换机的线插到了接入口。这时候如果接入口是边缘端口,它会直接把收到的 BPDU 丢掉,环路照成不误。
BPDU 保护解决这个问题:
stp bpdu-protection这是全局命令,开启后,边缘端口一旦收到 BPDU,会被立即 shutdown(进入 error-down 状态),同时上报告警。环路被物理切断,网络保住,代价是那个口不通了。
被关掉的口怎么恢复?两种方式:
# 方式一:手工恢复 interface GigabitEthernet 0/0/3 shutdown undo shutdown quit # 方式二:配置自动恢复 error-down auto-recovery cause bpdu-protection interval 300自动恢复的间隔建议设长一点,比如 300 秒。太短的话,问题没处理完,口一恢复又被打下去,反复抖动。这个配置有个前提:需要在全局开启,且 error-down 的原因要对应bpdu-protection。
5.2 根保护:防止下游设备抢根
根桥优先级是可以被下游设备改的。如果某台接入交换机被人为把优先级设成了 0,它就会抢走根桥位置,整张树的形状瞬间重排,本来走核心的流量绕到接入层去了,延迟飙升、带宽打满。
根保护配在面向下游的指定端口上:
interface GigabitEthernet 0/0/1 stp root-protection quit开启后,如果该端口收到了优先级更优的 BPDU(也就是有人在抢根),端口不会切换成根端口,而是直接进入 Discarding 状态,相当于把这个"捣乱"的分支隔离掉。核心设备的下行口全部配上就对了。
配的位置很关键,配错了不但没保护作用,还可能把自己搞挂。原则:根保护只配在根桥或者靠近根桥的指定端口上,配在根端口上没意义,因为根端口本来就该收更优 BPDU。
5.3 环路保护与 TC 保护
环路保护针对的是单向链路故障。如果链路只有收方向断了(发方向还通),设备一直收不到 BPDU,会以为上游设备挂了,把原本阻塞的口打开,环路就形成了。
interface GigabitEthernet 0/0/1 stp loop-protection quit配在根端口或替代端口上。开启后,如果长时间收不到 BPDU,端口不会自动放开,而是保持阻塞并告警,等链路恢复。
TC 保护针对的是拓扑变化泛洪。每次拓扑变化,设备会发 TC BPDU,其他设备收到后清 MAC 表,短时间内大量 TC 会让交换机 CPU 飙高。TC 保护限制单位时间内处理 TC 的次数:
stp tc-protection stp tc-protection threshold 5默认是 10 秒内处理 1 次(不同版本略有差异),配了阈值之后,超出的 TC 会被合并处理,避免 CPU 被打满。
5.4 保护特性的适用位置对照
这几个保护配混了很常见,我把它们放在一张表里,按"配在哪个端口"来记:
| 特性 | 配置位置 | 解决什么问题 | 全局还是接口 |
|---|---|---|---|
| 边缘端口 | 接终端的 Access 口 | 免 30 秒等待 | 接口 |
| BPDU 保护 | 全局开启,作用于所有边缘端口 | 边缘口误接交换机 | 全局 |
| 根保护 | 根桥的下行指定端口 | 下游设备抢根 | 接口 |
| 环路保护 | 根端口、替代端口 | 单向链路导致误放开 | 接口 |
| TC 保护 | 全局 | TC 报文泛洪打满 CPU | 全局 |
记住一个口诀:边缘防插错、根保护防抢根、环路保护防单向、TC 保护防泛洪。四句话对应四个场景,配之前先想清楚是哪个场景。
6. 配完不通时,我通常按这个顺序查
MSTP 的排障有个好处:它的问题类型很集中,基本跑不出几个固定原因。下面这个顺序是我自己磨合出来的,从最常见到最不常见,逐层往下推。
6.1 第一步:三台设备的域参数是否真的一致
别信"我配了",去敲display stp region-configuration,三台设备的输出逐行比对。我遇到过的情况包括:
- 一台写
region-name RG-CORE,另一台写region-name rg-core,大小写不同,摘要就不一样; - 修订级别一台是 1 一台是 0;
- VLAN 映射顺序不同,
instance 1 vlan 10和instance 1 vlan 10 30,虽然可能不摘要冲突,但语义已经不同了; - 配了但没敲
active region-configuration。
域不一致的典型现象是:display stp brief里所有端口都显示正常,但每个实例的树都是各自为政,跨设备看根桥不是同一个,甚至出现"两台设备都认为自己是根"的情况。这时候去display stp instance 1看 CIST Root/ERPC,如果每台的根桥 ID 都是自己,基本就是域没对齐。
6.2 第二步:业务 VLAN 在链路上放行了吗
display port vlan或者display vlan,确认互联口的 Trunk 放行列表里有目标 VLAN。这个错误在复制配置时特别容易发生:从 SW1 复制到 SW3,SW1 的端口对端是 SW2,允许的 VLAN 列表可能和 SW3 需要的不同。
现象是 ping 不通但生成树全绿。判断方法很简单:在 SW3 上display mac-address vlan 10,如果看不到 PC 的 MAC,说明 VLAN 10 的流量连 SW3 都没出去;如果能看到 MAC 但没有对端的,说明是上行链路的问题。
6.3 第三步:实例的根桥是不是你期望的那台
display stp instance 1输出的第一行MSTID 1,下面会显示根桥 ID。对比三台设备,看是不是都指向同一个根。如果发现某台设备的根桥指向了自己,说明它的优先级最低,去查它的stp instance 1 priority。
还有一种情况:优先级配对了,但 MAC 地址更小的那台被选成了根。这是正常规则,不是故障。如果业务要求某台特定设备当根,光调优先级不够,还得确认没有第二台设备优先级也是 0。
6.4 第四步:端口是不是被保护特性误伤
配了 BPDU 保护之后,如果某台交换机的互联口配成了边缘端口,一收 BPDU 就被 shutdown,现象是链路起不来,display interface brief显示 DOWN 或者 ERROR DOWN。去display error-down recovery看有没有记录,有的话undo shutdown恢复,然后把stp edged-port enable去掉。
根保护配错位置也会出问题。如果把根保护配在了接上游的口上,而上游发来的 BPDU 确实更优(因为它本来就是根),端口会被永久阻塞,业务直接断。这时候的现象是:链路物理 up,但生成树状态永远是 Discarding,且日志里有 root-protection 的告警。看到这类告警,第一反应就是去核对根保护配在哪个口。
6.5 eNSP 特有的几个坑
实验环境有些独有的问题,列出来省得你重复踩:
| 现象 | 原因 | 处理 |
|---|---|---|
| 端口全 DISCARDING | 设备刚启动,STP 还在收敛 | 等 30 秒 |
| 抓不到 BPDU | 抓包点选错链路 | 选互联链路,不是 PC 链路 |
| 改了配置没生效 | 忘了 active | 敲active region-configuration |
| PC ping 不通网关 | PC 没配网关或网关地址错 | 检查 PC 的 IP 配置 |
| 保存后重开配置丢失 | 没执行 save | save后确认 |
还有一点:eNSP 里同一台设备反复 shutdown/undo shutdown 端口,有时会残留状态,建议改配置后重启设备再验证,虽然慢,但结果干净。
7. 从三台设备推到真实网络
实验做完只是起点。真实网络里的 MSTP 要考虑的东西多得多,下面这几点是我认为最值得提前想清楚的。
7.1 实例数量不是越多越好
有人一上来就给每个 VLAN 建一个实例,觉得"隔离得越细越好"。实际上每个实例都要单独算树、单独维护状态机,实例越多,设备的 CPU 和内存开销越大,BPDU 也越多。一般建议实例数量控制在 4 到 16 个之间,VLAN 按业务类型分组映射。
分组的原则是看流量走向,不是看 VLAN ID 连不连号。比如办公区 VLAN 100-120 走一个实例,访客 VLAN 200-210 走另一个,语音 VLAN 300 单独一个实例(语音对时延敏感,路径要可控),视频监控 VLAN 400 一个实例。按业务分组,比按 ID 分组合理得多。
7.2 和 VRRP、堆叠的配合
二层树和三层网关是两个独立的平面,但它们必须对齐。典型错误是:实例 1 的根桥是 SW1,但 VLAN 10 的 VRRP 主用是 SW2,结果二层流量绕到 SW1 再回 SW2 出网关,路径白白多了一跳。
正确做法是让两者指向同一台设备:实例 1 的根桥是 SW1,那么 VLAN 10 的 VRRP 主也放在 SW1。这样二层最优路径和三层出口一致,流量走最短路径。配置上就是两套命令对齐,规划阶段就要定好。
堆叠场景更简单,两台设备逻辑上是一台,MSTP 的根桥选择直接落在堆叠系统上,不用考虑双根的问题。但堆叠分裂的时候,MSTP 会重新计算,这时候 MAD 检测必须先起作用,否则分裂后的两台设备各自当根,网络直接裂成两个。
7.3 排障命令清单
最后留一份我自己常用的命令清单,出问题时按顺序敲,比乱翻文档快:
display stp # 全局状态,确认模式是 MSTP display stp region-configuration # 域参数,三机对比 display stp brief # 端口角色状态总览 display stp instance 1 # 单个实例的根桥和开销 display stp interface GigabitEthernet 0/0/1 # 单端口细节 display stp topology-change # 拓扑变化次数 display stp tc-bpdu statistics # TC 收发统计 display error-down recovery # 被保护关掉的端口记录 display mac-address vlan 10 # MAC 学习情况这份清单的价值在于顺序:先看全局模式对不对,再看域,再看端口,最后才看细节。顺序反了,容易在细节里绕圈。
我在实验室带新人的时候,通常让他们把上面这套拓扑从零配三遍:第一遍照着敲,第二遍不看命令敲,第三遍故意配错一个域参数然后自己排查出来。第三遍是最有价值的,因为真实的故障从来不是按章节出现的,它总是藏在某个你没想到的地方——比如忘了 active,比如把边缘端口配到了互联口上,比如修订级别差了一位。这些东西写不进文档,只能自己踩过一遍才记得住。
MSTP 的命令不多,真正花时间的是理解它为什么这么设计。想明白"为什么要分域、为什么实例要映射 VLAN、为什么总根和实例根是两个概念",剩下的就是熟练度问题了。