第4章 优先级决议算法:谁说了算?

搞了这么多年网络,我见过不少工程师在自协商失败后一头扎进物理层,换线、换端口、调电压,折腾半天发现根本问题是——双方对协商结果的"优先级理解"不一致。说白了,自协商不是单纯地"比大小",它有一套完整的优先级决议算法。不理解这套规则,你修故障就跟闭着眼拆炸弹一样。

一句话总结:自协商结果由"速度优先,双工次之"的层级规则决定。速度相同比双工,双工相同比能力优先级。这是IEEE 802.3u规定的铁律。

4.1 为什么要有优先级规则?

自协商的本质,是两端设备交换各自的能力集——支持哪些速率、哪些双工模式,然后从中找一个"双方都支持且最优"的公共组合。但问题在于:能力集可能有多个交集。

举个例子:A端支持1000M全双工、100M全双工、10M全双工;B端支持1000M全双工、100M半双工。交集是什么?1000M全双工和100M全双工(如果B也支持全双工的话,但B只支持100M半双工?这里虚构,只是说明交集)实际上典型场景:一端想跑1000M全双工,另一端只支持100M半双工,交集是空的?不,自协商必须有一个结果,哪怕退到最低档。所以需要一套规则来"仲裁"。

我记得有一次在数据中心,两根光纤,交换机与服务器直连,协商出来只有100M半双工。性能惨不忍睹。排查到最后,发现是服务器网卡固件版本太老,把1000M全双工的能力位给丢了。但交换机端保留了1000M全双工能力。按照优先级规则,双方能力交集是1000M半双工?不对,1000M只有全双工模式,所以实际上交集为空,结果退到10M半双工。那为什么看到100M半双工?因为网卡内部又通过"并行检测"(Parallel Detection)用了一个独立机制…… 这个后面章节会细讲。不过核心就是:优先级决议决定了所有退让路径。

4.2 核心优先级规则

直接上硬货。自协商的优先级决议算法分三层:

  1. 速率优先。先看速率。谁的速率高,谁被优先选择。比如1000M > 100M > 10M。
  2. 双工模式次之。在相同速率下,全双工优先于半双工。
  3. 能力优先级。如果速率和双工都一样(比如两边都只有100M全双工),那就走IEEE定义的固定能力优先级表格——HCD(Highest Common Denominator)算法会直接映射到一个优先级数值,数值小的优先(实际协定中更低编号的Base Page位优先级更高)。

这个算法其实是一个"从高到低的穷举匹配"。把两端的能力集按照速率/双工降序排列,逐项检查对方是否支持,第一个匹配的就是结果。

常见能力组合及其优先级(从高到低)
速率 双工模式 优先级(1最高)
1000BASE-T全双工1
1000BASE-T半双工(极少用)2
100BASE-TX全双工3
100BASE-TX半双工4
10BASE-T全双工5
10BASE-T半双工6
避坑提示:我曾经以为速率优先级是的——100M全双工肯定比10M全双工优先。没错。但如果有另一端只支持100M半双工,而另一端支持100M全双工,结果会是100M半双工,因为半双工比全双工"低一级",但速率一致时,全双工优先于半双工?注意这里:全双工优先于半双工的意思是,如果对方也支持全双工,那就选全双工。但如果对方只支持半双工,那交集就是100M半双工。所以最终结果是"双方都支持的最高优先级组合"。

4.3 典型场景分析

只看理论不太过瘾,我们来拆三个真实案例。

场景一:交换机与PC协商为100M半双工

现象:交换机端口指示灯显示100M橙色(半双工),PC端显示100M半双工。网络延迟高,丢包严重。

分析:你看,两个设备都支持1000M全双工。为什么只跑到100M半双工?我最初怀疑是线缆质量(Cat5e但距离超过100米),但换短跳线依旧。后来抓包发现,交换机端口强制设成了100M全双工——等等,强制模式会关闭自协商,但这里交换机显示自协商成功?实际上,有些交换机在端口被强制设置后,仍然会发送自协商FLP burst并试图协商。强制100M全双工的端口会在FLP中只声明100M全双工能力。PC端自协商能力集包括1000M全双工、100M全双工、100M半双工。按照优先级:先看速率1000M全双工,交换机不支持,跳过;然后看100M全双工,交换机支持(强制设置),匹配成功,结果应为100M全双工。但实际是半双工?原因:PC或交换机的某些实现会把"强制模式"的FLP能力位设置不完整,导致接收端误判。这种情况下,优先级决议算法本身没问题,是物理层信号残缺导致能力集错误。

场景二:两端强制不同速率

现象:一端强制1000M全双工,另一端强制100M全双工。链路无法up。

分析:强制模式会完全禁用自协商。两端的FLP都不发送,也不会监听。所以没有任何能力集交换。没有协商,就没有决议。链路建立失败。这时候优先级算法根本用不上。嗯,这也是常见误区——很多人以为强制模式也是一种"半协商",其实不是。强制模式下,物理层直接采用固定配置,不参与自协商过程。如果两边强制不一致,就断。

场景三:混合速率迁移(100M→1000M)

现象:旧PC只有100M网卡,新换成千兆网卡。但协商结果始终为100M全双工。

分析:可能原因是交换机端口配置了"速率协商"但开启了"自动协商仅100M"的acl?实际上更常见的是:交换机端口存在"自适应"故障,导致在FLP交互中误以为对方不支持1000M。我们可以尝试用"重启自协商"命令(如disable / enable端口,或网卡驱动重新协商)。如果依旧不行,检查网线是否四对线全部连通。1000BASE-T需要四对线,100BASE-TX只需要两对。如果中间有个老旧配线架只接了1、2、3、6针,千兆就会降级到百兆。

严重警告:千万不要在生产链路上同时设置强制模式和对端自协商。这会导致"双工失配"——一端自协商出100M全双工,另一端强制为100M半双工,链路能通但性能极差。优先级决议算法在这里是不生效的,因为强制端口根本不参与协商。我曾经在一个银行的灾备中心踩过这个坑,业务中断半小时,全是冷汗。

4.4 优先级决议流程图

下面这张SVG图,我画了完整的决议流程。说白了,算法的灵魂就是"选两边的最大值,但只取公共部分"。

自协商优先级决议流程图 开始协商 读取本地与远端能力集 (通过FLP/NLP交换Base Page) 计算公共能力集 (交集可能为空) 交集为空 → 并行检测/退至最低 (10M半双工或链路Down) 最终结果:最低公共能力 交集非空 → 应用优先级规则 (速度优先→双工优先→能力位优先级) 最终结果:最高优先级公共能力 注意:强制模式下跳过此流程,直接使用端口配置值

从图中你能看到,核心分叉就是"交集是否为空"。空的时候,自协商会尝试并行检测(Parallel Detection)——一种只检测链路脉冲但不交换页面的补救机制,往往退到最低速率半双工。非空的时候,就按优先级排序选最佳。

4.5 小结:故障诊断中的优先级"盲点"

我从实际排障经验里总结出三个常见的优先级相关盲点:

  • 盲点1:以为速率越高就一定被选。忘了检查对方能力集里是否有这个速率。速率优先的前提是“双方都支持”。
  • 盲点2:混淆了“全双工优先”与“全双工必定被选”。如果对方只支持半双工,那全双工优先也没用,最终只能是半双工。
  • 盲点3:忽视能力优先级中的“HCD固定映射”。1000M半双工(极少用)的优先级实际高于100M全双工?不,按IEEE标准,1000M半双工优先级编号是2,100M全双工是3,所以1000M半双工优先。但现实中几乎没设备支持1000M半双工,所以这问题很少遇到……我曾经调试过一台老IBM服务器,它支持1000M半双工,结果导致降速。

理解这套优先级算法后,你再去看自协商结果,就能迅速判断:是能力集缺失,还是优先级排位错误。多数情况下,故障就出在能力集——要么是一端少声明了一个能力,要么是受到噪声干扰把能力位翻转了。下一小段我们准备聊FLP的帧结构,不过那是后话了。先把优先级规则刻在脑子里,后面修故障就稳了。