简介:IEC 62439-3:2016 第三版标准文档,面向工业通信网络与高可用性自动化领域,系统阐述并行冗余协议(PRP)和高可用性无缝冗余(HSR)的技术要求、实现方法与工程应用,适合工业自动化、电力控制、轨道交通等场景的网络设计、运维工程师及研究人员查阅。资料为1个PDF文件,共358页,压缩包约6.65MB,保留原版标准排版、图表与条款结构,便于按章节检索协议框架、配置诊断及测试流程。内容覆盖PRP双路径冗余与HSR双环网传输机制,并涉及单点故障处理、网络集成、部署与验证要点,可作为方案设计、故障分析和标准对照的参考底稿。已有393人学习,适合需要深入理解工业冗余网络规范的中高级技术人员。
1. 双网都通、拔线却丢了几十毫秒:问题不在冗余协议选错
在一个自动化产线的联调现场,两个物理上完全隔离的 LAN、两台交换机、一块双口网卡,配置看上去没有任何问题。拔掉任意一根网线,链路指示灯瞬间切换,交换机日志干净,可上位机的数据流还是断了四十多毫秒。查到最后发现,问题既不在 IEC 62439-3 标准本身,也不在交换机,而是发送侧根本没做链路层复制——两块网卡各自走 IP 层发出,序列号各算各的,接收端自然认不出这是同一帧的两份拷贝。PRP 和 HSR 这两个协议在工业现场被提及的频率极高,但真正把「复制点在哪一层、序列号谁来发、接收端凭什么判重」这三件事讲透的材料并不多。手上这份 IEC 62439-3 第三版(2016-03 发布)把 PRP 与 HSR 从拓扑、节点结构、帧格式到监督帧和常量定义全部展开,适合做冗余网络设计、冗余交换设备开发、现场验收与故障定位的工程师逐节对照。三百多页的正文不适合从头读到尾,按落地顺序拆开看效率最高。
2. PRP 的复制与丢弃:DANP 节点怎么做到切换零感知
PRP 最容易理解错的一点,是很多人把它类比成服务器上的双网卡绑定或者链路聚合。这两者的目标完全不同:链路聚合是为了带宽和链路级容错,切换过程依赖协议收敛;PRP 追求的是应用层完全感知不到故障发生过,它靠的是「同一帧发两份、走两条永不交汇的路径、接收端去重」。理解了这个模型,后面所有的参数和坑才有落脚点。
2.1 两份帧、一个序列号:链路层复制模型
PRP 的核心节点叫 DANP(Doubly Attached Node implementing PRP,双连接 PRP 节点)。它对外呈现两个独立的以太网端口,分别接到两个物理隔离的 LAN 上,这两个 LAN 在二层不能有任何连通路径——这一点是 PRP 能成立的前提,因为一旦连通就成环了,普通交换机会直接泛洪到瘫痪。
发送侧的动作发生在链路层:上层协议栈交下来一帧,DANP 把它复制成完全相同的两份,每份尾部追加 6 字节的 RCT(Redundancy Control Trailer,冗余控制尾),然后分别从端口 A 和端口 B 发出。RCT 三个字段,各 2 字节,全部大端:
| 字段 | 长度 | 作用 | 落地要点 |
|---|---|---|---|
| 序列号 Sequence Number | 2 字节 | 标识同一帧的两个副本 | 由同一个 16 位计数器统一分配,两个端口共用,回绕后继续 |
| LSDU 大小 | 2 字节 | 载荷长度 | 接收端用它反推 RCT 的起始位置,同时可用于发现截断帧 |
| PRP 后缀 | 2 字节 | 固定值 0x88FB | 接收端据此确认这是 PRP 帧而不是普通帧尾 |
接收侧的动作更简单:先到的副本直接上交协议栈,后到的副本按序列号查表,命中就丢弃。这里没有协商、没有握手、没有生成树,两个 LAN 之间也没有任何协议报文往来。这就是 PRP 切换时间在理论上等于零的原因——它不是「切换得快」,而是压根没有切换这个动作,只是另一条路上的那一份刚好也到了。
提示:RCT 位于帧内容里,不属于 FCS。用抓包工具时网卡会剥掉 FCS,但 RCT 仍然保留在帧尾,只要 snaplen 足够就能读到。
2.2 拓扑选型:双独立 LAN、双环还是混合
标准在 PRP 部分把 LAN 的形态分为线性和总线、环网两类,实际项目里还要多考虑一种「两套 LAN 各自成环」的混合形态。选型不看理论优劣,看故障域和布线成本。
| 拓扑形态 | 单点故障影响 | 布线成本 | 适用场景 | 主要约束 |
|---|---|---|---|---|
| 两个独立线性/总线 LAN | 一根线或一个端口故障,另一套 LAN 完整承载 | 双倍线缆与端口 | 机柜内设备密集、距离短 | 两个 LAN 严禁二层互通 |
| 两个独立环网 LAN | 环上单点断开后环内自愈,PRP 侧再兜一层 | 环网省线,但仍需两套 | 沿产线分布、距离较长 | 环网协议与 PRP 相互独立,需分别验证 |
| PRP + HSR 混合 | 边缘用 HSR 环,骨干用 PRP 双 LAN | 折中 | 大型系统分区 | 跨域节点必须是 RedBox 或 QuadBox |
一个常见误判是把 PRP 当成「更快的环网协议」。环网协议(不论哪种)解决的是链路断开后的路径重构,重构期间一定有丢帧;PRP 解决的是让同一帧永远有两条独立路径,两者不是替代关系。节点数量少、布线受限的场合,HSR 更划算;节点分散、单点价值高、又不想让每台设备都换成支持 HSR 的芯片,PRP 更省事。
2.3 四种接入角色:DANP、SAN、RedBox、VDAN
现场设备不可能全部支持双连接,标准为此定义了一套接入体系,选型时先把每个设备归到下面四类里:
| 角色 | 端口数 | 冗余能力 | 典型用途 |
|---|---|---|---|
| DANP | 2 个 PRP 端口 | 完整,端到端 | 控制器、关键 I/O、上位机 |
| SAN(单连接节点) | 1 个普通端口 | 无 | 普通传感器、非关键设备 |
| RedBox(冗余盒) | 2 个冗余侧 + 1 个 interlink | 代理 SAN 接入冗余网 | 把一批单连接设备挂进 PRP/HSR |
| VDAN(虚拟双连接节点) | 逻辑上 2 个 | 由 RedBox 代为完成 | RedBox 背后的 SAN 在管理面上的身份 |
RedBox 是这套体系里工作量最大的部件。它要维护一张 ProxyNodeTable(代理节点表),记录哪些 MAC 地址是从 interlink 侧学来的、哪些是冗余侧本地的。跨侧转发时的规则、组播怎么处理、监督帧怎么代发,标准里都有明确条款。做设备开发的人如果只实现了单播转发而漏掉组播和 ProxyNodeTable 的刷新时机,现场表现就是「单播正常、一上组播就乱」。
2.4 落地配置步骤与一个能跑的 RCT 校验脚本
这一节是可以直接抄作业的部分。目标很明确:搭起最小可用的 PRP 链路,并且用抓包证明「两个端口上确实是同一帧的两份」。
第一步,物理上准备两套完全独立的 LAN,交换机之间不插任何互联线,也不配置跨交换机的聚合或堆叠。
第二步,把 DANP 的两个端口分别接入两套 LAN。如果用的是支持 PRP 的网卡,驱动会向上层暴露一个虚拟接口,业务绑定这个虚拟接口而不是物理口。
第三步,确认两个 LAN 之间没有任何三层路由或二层桥接。这一步是后面所有坑的源头,务必先确认再往下走。
第四步,抓包比对。下面这组命令在两个物理口上分别落盘,保留完整帧以便读到帧尾:
# ethA / ethB 分别对应两套独立 LAN 上的物理口 # -s 0 保留完整帧,否则默认 snaplen 会截断,读不到帧尾的 6 字节 RCT tcpdump -i ethA -s 0 -w prp_a.pcap # 另开一个终端 tcpdump -i ethB -s 0 -w prp_b.pcap # 只想快速确认 PRP 帧是否真的存在,可以直接按后缀 EtherType 过滤 tcpdump -i ethA -s 0 -e ether proto 0x88fb抓完包,用下面这段脚本把每帧的序列号和载荷长度读出来,两个文件一比对,去重逻辑是否成立就一目了然:
import struct PRP_SUFFIX = 0x88FB # PRP 帧尾固定标识 ETH_HDR_LEN = 14 # 不含 VLAN 标签的以太网头长度 def parse_prp_trailer(frame: bytes): """从完整以太网帧中解析帧尾的 RCT(6 字节)""" if len(frame) < ETH_HDR_LEN + 6: return None # RCT 紧贴帧尾:序号(2) + LSDU大小(2) + 后缀(2),全部大端 seq, lsdu_size, suffix = struct.unpack(">HHH", frame[-6:]) if suffix != PRP_SUFFIX: return None # 不是 PRP 帧,或抓包被截断导致偏移错位 # LSDU 大小可用于反向校验:帧长应约等于 14 + lsdu_size + 6 expected = ETH_HDR_LEN + lsdu_size + 6 return { "seq": seq, "lsdu_size": lsdu_size, "len_ok": abs(len(frame) - expected) <= 4, # 容忍 VLAN 标签差异 } # 用法:把 pcap 里的帧逐条喂进来,按 seq 建两个集合,看交集是否接近全集三个参数的含义需要说清楚。seq是 16 位序列号,同一个 DANP 的两个端口必须共用同一个计数器,这是判断复制点是否放在链路层的唯一硬证据——如果两个 pcap 里同一帧的seq不一致,说明复制发生在更上层,去重必然失效。lsdu_size是载荷长度,接收端用它定位 RCT 起点,也是在长度异常的畸形帧上做防御的依据。suffix固定为 0x88FB,任何不等于这个值的帧都不该进 PRP 的去重流程。len_ok那行是经验性的自校验,容忍了 VLAN 标签带来的 4 字节偏差,实际项目里 VLAN 标签在不在、打在哪一层,会直接影响偏移计算,先把这一项跑通再谈性能。
2.5 重复帧判别窗口与网络监督
去重的实现方式标准给了两种模式。Duplicate Discard 是正常工作模式:按序列号维护一个滑动窗口,窗口内已见过的序列号对应的帧直接丢弃。窗口大小决定了能容忍多大的乱序,太小会在链路时延抖动大时误丢,太大会增加内存占用和判断开销。Duplicate Accept 模式仅用于测试,它把重复帧也上交,用来验证「两份确实都到了」,生产环境不能开。
监督机制靠 PRP_Supervision 帧完成。这类帧按固定周期从每个端口发出,携带发送节点的标识和端口信息,接收端收到后更新 NodesTable。这张表是排障的核心数据源:哪个节点、哪个端口、最后一次收到监督帧是什么时候。现场定位断点时,先看 NodesTable 里哪一行的最后更新时间停住了,再顺着那一行去找物理链路,比逐个拔线快得多。
注意:监督帧使用的是标准分配的组播地址段,交换机上的组播抑制、IGMP snooping 都有可能把它拦掉,接入前先把这类地址加进白名单。
3. HSR 环网设计与节点转发规则:从 DANH 到 QuadBox 的取舍
PRP 需要两套网络,布线成本是硬支出。HSR 换了个思路:只用一个环,但让每一帧同时从两个方向绕环传播,接收端先到先收、后到丢弃。省了一半线缆,代价是环上每个节点都要参与转发,带宽和时延变成了全环共享的资源。这个代价在节点数量上会非常直观地体现出来。
3.1 HSR 标签与「先到先服务」:环网冗余和 PRP 的本质差别
HSR 节点发送时,在源 MAC 之后插入 6 字节的 HSR 标签,然后向环的两个方向各发一份。标签结构与 PRP 的 RCT 位置相反——它在帧头而不是帧尾:
| 字段 | 长度 | 含义 | 说明 |
|---|---|---|---|
| HSR EtherType | 2 字节 | 固定 0x892F | 接收端据此识别 HSR 帧 |
| 路径 / LSDU 大小 | 2 字节 | 高 4 位为路径标识,低 12 位为载荷长度 | 路径字段用于多环互联时标识来源 |
| 序列号 | 2 字节 | 16 位,发送节点统一分配 | 去重依据,与 PRP 语义一致 |
和 PRP 最本质的差别在于「谁参与冗余」。PRP 里两个 LAN 内的交换机是完全无感的普通设备,冗余只发生在两端节点;HSR 里环上每一个节点都是转发参与者,帧每经过一跳,路径字段就要更新一次。这意味着 HSR 的故障切换虽然同样接近零(反向路径本来就在传),但故障恢复后的流量分布、环网规模、每跳的处理时延,全都要提前算。
PRP 与 HSR 的对比放在一张表里更清楚:
| 维度 | PRP | HSR |
|---|---|---|
| 拓扑 | 两个物理独立 LAN | 单个环或互联环 |
| 冗余域 | 端到端,网络对节点透明 | 逐跳,每个节点都转发 |
| 帧标识位置 | 帧尾 RCT | 帧头 HSR 标签 |
| 对中间设备要求 | 普通交换机即可 | 必须是 DANH 或 RedBox |
| 布线成本 | 双倍 | 环比星型省,但每节点两个口 |
| 主要瓶颈 | 两套网络的运维一致性 | 环上节点数与共享带宽 |
3.2 DANH 的四个入口与转发规则表
HSR 的双连接节点叫 DANH(Doubly Attached Node implementing HSR)。它有两个 HSR 端口和一个本地链路层接口,三个口之间怎么转发,标准给了明确的规则,落到实现上就是一张四行的判断表:
| 入口 | 目的地址 | 动作 |
|---|---|---|
| 本地链路层接口(来自上层协议栈) | 任意 | 复制两份,插入标签,分别从两个 HSR 端口发出 |
| HSR 端口 A | 本节点 | 上交本地接口,记录序列号用于后续去重 |
| HSR 端口 A | 其他节点或组播 | 从端口 B 转发出去,序列号不变,更新路径字段 |
| HSR 端口 A | 序列号已见过的重复帧 | 直接丢弃,不转发不上交 |
这四行里最容易实现错的是第三行。转发时序列号必须原样保留,只有路径字段可以动;有些实现为了「顺便做点流量统计」改了序列号,结果下游节点的去重表全部失效,表现是网络越跑越慢、重复帧越来越多,抓包看每个帧的序列号都是新的——这类问题非常隐蔽,属于典型的黑匣子故障。
另一个细节是组播。单播可以去重,组播地址没有「目的节点」这个概念,环上每一份都会被多个节点接收,去重规则和单播并不完全一样。做设备开发时,组播帧的处理路径建议单独写一遍测试用例,不要指望单播通过就能覆盖。
3.3 RedBox 与 QuadBox:单连接设备和跨环互联怎么选
RedBox 在 HSR 里的角色和 PRP 里类似,但结构不同:冗余侧是两个 HSR 端口串在环上,另一侧是 interlink,接单连接设备。它要做的事情包括从 interlink 收到的帧打上标签注入环、从环上收到的帧判断目的地址决定是上交还是继续转发、以及维护 ProxyNodeTable 记录 interlink 背后的设备。
QuadBox 是 RedBox 的背靠背组合,用来把两个 HSR 环连起来。它不是简单的二层桥接——如果只是桥接,两个环的流量会互相泛洪,环网的非环结构立刻被破坏。标准对 QuadBox 单独列了规范,处理的是跨环帧的标签重写、路径字段的映射、以及避免帧在两个环之间来回震荡。
选型上的经验判断:
| 场景 | 推荐 | 理由 |
|---|---|---|
| 环上全部是关键设备,且都支持 HSR | 纯 DANH 环 | 结构最简单,无代理开销 |
| 环上要挂一批老设备 | 就近部署 RedBox | 代理开销集中,便于集中管理 |
| 两个物理分区各自成环,需要互通 | QuadBox | 避免直接桥接造成的泛洪 |
| 分区之间流量很小 | 考虑 PRP 骨干 + HSR 边缘 | 跨区只走两条独立链路 |
QuadBox 的部署位置很关键。它两侧各接一个环,位置选在流量最集中的交汇点,跨环帧的路径最短;如果选在环的末端,跨环流量要在环上绕大半圈,最坏时延会明显上升。
3.4 环网规模、CoS 与时钟同步的相互牵制
HSR 环上节点数不是随便加的。每一帧都要经过每一个中间节点转发,环越大,最坏情况下的累计转发时延越高,同时环上共享的带宽被切得越碎。第三版标准在 HSR 侧补充了 CoS(服务等级)、时钟同步和确定性介质访问这几节,正是因为环网规模上去之后,流量优先级和时钟同步精度会互相影响。
一个粗略的估算方式:最坏路径时延约等于「环上节点数的一半 × 单跳转发时延 + 链路传播时延」。单跳转发时延取决于设备实现,存储转发和直通转发差一个数量级,必须先实测再代入。节点数每翻一倍,最坏时延和带宽竞争都同步恶化,所以环网规模要留出余量。
时钟同步方面,HSR 环里的同步报文同样会被复制两份绕环传播,接收端去重之后才进同步算法。如果去重窗口配置不当,同步报文被误判为重复而丢弃,表现为时钟精度周期性劣化,且很难从同步协议自身的日志里看出来。这类问题的排查入口在 HSR 层的统计计数,而不是时钟模块。
3.5 一次 HSR 环网搭建与验证分步
从零搭一个 HSR 环,按下面的顺序走,可以少走很多弯路。
第一步,确定环上节点清单,标注每个节点是 DANH 还是 RedBox,RedBox 后面挂几台设备。这一步决定了 ProxyNodeTable 的规模和监督帧的数量。
第二步,按环的物理走向布线,注意两个方向要真正物理分离。有些现场为了省线槽把两个方向的线绑在一起,机械损伤一来两条路径同时断,冗余形同虚设。
第三步,逐台设备配置,先只上电两台,验证双向转发是否正常,再逐台加入。一次性全上电,出问题时无法判断是哪一台引入的。
第四步,用监督帧确认环上每个节点都被看见,NodesTable 的行数与节点清单对得上。
第五步,做故障注入。逐个拔掉环上每一段链路,记录业务中断情况。正常结果应该是零丢帧或仅有极少量由设备实现引入的瞬断,如果每次拔线都断几十毫秒,问题在节点实现的去重或转发路径上,不在协议本身。
# 环网验证阶段的持续探测,记录每次故障注入的时间窗口 # -i 指定间隔,-O 表示不等待回复即发下一包,便于观察丢包位置 ping -i 0.01 -O -c 20000 192.0.2.10 | tee hsr_ping.log # 抓包侧同时记录,便于事后对齐时间戳 tcpdump -i hsr0 -s 0 -w hsr_ring.pcap -G 60 -W 10这两条命令的价值在于「时间对齐」。故障注入的瞬间、ping 丢包的时间点、抓包里序列号断档的位置,三者对得上,才能判断丢的是哪一段。只有 ping 日志没有抓包,最多知道丢了;只有抓包没有业务侧日志,无法确认上层是否真的受影响。
4. 帧格式与监督帧:把 RCT、HSR 标签、监督帧拆到字节级
协议层的争论到最后往往落在字节上。现场两台设备互不相认,各自都说自己按标准实现,唯一能定胜负的就是抓下来的帧逐字段比对。这一章把两类帧的关键字段拆开,配合一段能直接跑的解析脚本。
4.1 PRP_Supervision 帧逐字段拆解
PRP 的监督帧用来维持节点之间的可见性,周期性发送,接收端据此刷新 NodesTable。结构与普通数据帧的差别在于:它不带业务载荷,帧尾仍然挂 RCT,中间部分放的是监督信息。
| 字段 | 长度 | 取值与含义 | 校验要点 |
|---|---|---|---|
| 目的 MAC | 6 字节 | 标准分配的监督用组播地址,前缀 01-15-4E | 交换机若拦截组播,此帧直接消失 |
| 源 MAC | 6 字节 | 发送端口自身的 MAC | 两个端口应发出源 MAC 不同的两份 |
| 长度/类型 | 2 字节 | 与普通帧一致 | 注意 VLAN 标签是否插入 |
| 监督载荷 | 变长 | 版本、监督类型、发送节点与端口标识、节点列表 | 字段顺序以标准对应条款为准 |
| RCT | 6 字节 | 序列号 + LSDU 大小 + 0x88FB | 与数据帧格式一致 |
排查时按顺序看三件事:目的 MAC 对不对、两个端口的源 MAC 是否不同、RCT 后缀是不是 0x88FB。三样都对还收不到,问题就落到交换机的组播策略上了。
4.2 HSR 标签与 HSR_Supervision 帧的差异点
HSR 的监督帧同样周期性发送,但它多了一层结构:HSR 标签插在源 MAC 之后,然后才是监督载荷。和 PRP 相比有三个明显差异:
| 对比项 | PRP 监督帧 | HSR 监督帧 |
|---|---|---|
| 标识位置 | 帧尾 RCT | 帧头 HSR 标签 |
| 传播方式 | 两个独立 LAN 各一份 | 环的两个方向各一份,逐跳转发 |
| 路径字段 | 无 | 有,用于标识来源路径 |
| 去重依据 | 帧尾序列号 | 帧头序列号 |
| 接收端更新对象 | NodesTable | 本地节点表与路径信息 |
HSR 监督帧的路径字段在多环互联时特别有用。跨 QuadBox 的帧,路径字段会反映出它从哪个环来、经过哪条路径,排障时能直接看出帧是不是绕了远路。
4.3 用一段脚本同时解析 PRP 尾部与 HSR 标签
下面这段脚本把两种帧的识别逻辑放在一起,输入是完整以太网帧,输出是可读的字段。抓包文件逐帧喂进来即可批量处理:
import struct PRP_SUFFIX = 0x88FB # PRP 帧尾标识 HSR_ETHERTYPE = 0x892F # HSR 帧头标识 ETH_HDR_LEN = 14 def classify(frame: bytes): """先看帧头有没有 HSR 标签,再看帧尾有没有 RCT""" if len(frame) < ETH_HDR_LEN: return {"type": "truncated"} # HSR 标签紧跟在源 MAC 之后,即偏移 12 字节处 etype = struct.unpack(">H", frame[12:14])[0] if etype == HSR_ETHERTYPE: path_size, seq = struct.unpack(">HH", frame[14:18]) return { "type": "HSR", "path": (path_size >> 12) & 0x0F, # 高 4 位:路径标识 "lsdu_size": path_size & 0x0FFF, # 低 12 位:载荷长度 "seq": seq, # 16 位序列号 } # 帧尾再试一次 PRP if len(frame) >= ETH_HDR_LEN + 6: seq, lsdu_size, suffix = struct.unpack(">HHH", frame[-6:]) if suffix == PRP_SUFFIX: return { "type": "PRP", "seq": seq, "lsdu_size": lsdu_size, } return {"type": "plain"}解析顺序不能反。HSR 标签在帧头,先判断一次就能快速分流;PRP 的 RCT 在帧尾,只能靠后缀值确认,误判率比帧头判断高,所以要放在后面。path字段只有 4 位,取值范围 0 到 15,多环互联时用来区分来源,单环场景下通常是固定值,看到它频繁变化就说明流量跨了环。lsdu_size在两种帧里含义一致,但 HSR 由于每跳不改长度,可以用来做端到端的一致性校验;PRP 则可以用来发现中途被截断的帧。
提示:脚本里对帧长的判断容忍了几个字节的偏差,是为了兼容带 VLAN 标签的帧。生产环境做严格校验时,应该先解析 VLAN 标签再计算偏移。
4.4 拿监督帧做故障定位:NodesTable 的读法
NodesTable 不是一份「设备清单」,而是一份「最近一次听见某节点的时间表」。读它的正确姿势是看时间维度而不是存在维度。
正常状态下的特征:所有节点的最后更新时间都在一个监督周期之内,端口 A 和端口 B 各有独立记录,序列号连续无大跳变。异常状态通常有三种形态。一是某节点的更新时间停住,其他节点正常——问题在那台设备的链路或电源,不在环上。二是某节点的 A 口正常、B 口停住——冗余已经降级为单路,业务暂时没影响,但下一次故障就是全断,必须立刻处理。三是所有节点的时间戳同时大幅跳跃——问题在监督帧本身的发送周期上,可能是设备负载过高,也可能是监督帧被限速或丢弃。
第三种最容易被忽略,因为业务流量看起来完全正常。等到某天真的断了一根线,才发现监督机制早就失效,冗余状态从未被验证过。定期导出 NodesTable 做对比,比事后翻日志有用得多。
5. 避坑清单:五个把 PRP/HSR 现场搞翻车的真实触发条件
标准和实现之间的差距,基本都藏在这几类问题里。下面五条按「现象 → 原因 → 解决」记录,都是反复出现过的形态,不是理论推演。
5.1 两个 LAN 被悄悄打通:最隐蔽也最致命
现象:PRP 链路刚接通时一切正常,运行几小时后广播流量持续攀升,交换机 CPU 打满,业务开始丢包。抓包能看到同一个序列号的帧在两个 LAN 上都出现,且数量远超预期。
原因:两个物理独立的 LAN 之间存在一条没有被告知的二层通路。常见的来源是某台设备双归接入了两个 LAN、某个管理口被顺手插到了另一套交换机上、或者调试时临时拉的跳线忘了拔。PRP 的两个 LAN 一旦连通就形成了环,普通交换机没有环网保护,泛洪会迅速放大。
解决:建立一份「两个 LAN 之间不允许存在任何二层通路」的强制检查项,接入前用生成树或环路检测工具扫一遍。运行期间定期比对两个 LAN 的 MAC 地址表,如果同一个 MAC 在两个 LAN 的交换机上都学到,基本可以确定有桥接。这条属于必须走一遍的后悔药,不能靠人记。
5.2 序列号错乱导致去重完全失效
现象:抓包显示两个端口上的帧内容完全一致,但接收端把两份都上交了,应用层收到重复数据,日志里出现大量重复事件。逐帧比对会发现两份帧的序列号不一样。
原因:复制动作放在了 IP 层或应用层,两块网卡各自维护独立计数器。也可能是在链路层复制了,但驱动程序在多队列场景下每个队列各有一个计数器。这两种情况下,接收端看到的永远是两个不同的序列号,去重表根本命中不了。
解决:序列号必须由同一个计数器在「即将交给物理口发送之前」统一分配,两个端口共用。做设备开发时,把这一条写进驱动的单元测试;做集成时,用前面那段脚本比对两个 pcap 的序列号集合,交集必须接近全集,否则就是复制点放错了位置。
5.3 环网节点数超标,突发流量成片丢
现象:HSR 环上节点从十几个增加到二十几个之后,周期性突发流量开始出现规律性丢包,丢包集中在环的某一段,且与业务负载高峰吻合。
原因:HSR 环的带宽是共享的,每个节点都要转发经过它的所有帧。节点数增加意味着同一份突发流量在环上被复制和转发的次数增加,中间节点的出口队列在突发瞬间被打满。这不是协议问题,是容量规划问题。
解决:先实测单跳转发时延和单节点吞吐,再按最坏路径跳数反推可承载的突发量。控制环上节点数,把非关键设备挪到 RedBox 背后而不是直接挂在环上。对组播和广播做限速,这两类流量在环上的放大效应比单播明显得多。
5.4 监督帧被交换机拦掉,节点表永远是空的
现象:链路完全正常,业务数据也能通,但 NodesTable 一直是空的,或者只有本地节点。换一台交换机就好了。
原因:监督帧用的是标准分配的组播地址,交换机的组播抑制、IGMP snooping、或者安全策略把它当成未知组播丢弃了。有些设备默认开启「未知组播不转发」,恰好命中。
解决:把监督帧使用的组播地址段加入交换机的白名单,关闭该地址段的组播抑制。如果交换机支持静态组播配置,直接把相关端口配置成该组播组的固定成员。这一条在设备选型阶段就该确认,等到现场才发现,替换交换机的成本很高。
5.5 恢复时间不是零,问题在应用层而不在协议
现象:故障注入时,网络层的抓包显示零丢帧,但应用层的日志记录了几十毫秒的数据中断。两边的结论互相矛盾。
原因:冗余做到了链路层,但应用绑定的还是单块物理网卡,或者用的是 TCP 长连接,链路切换虽然没丢帧,但连接状态或缓冲区出了问题。另一种情况是上位机只监听了一个 IP,另一个 LAN 上的帧虽然到了网卡,但没进到应用。
解决:应用必须绑定虚拟接口而不是物理网卡,让冗余对上层完全透明。协议选择上,对时延敏感的控制数据优先用无连接方式,避免重传机制把瞬断放大。验证时不要只看 ping,要用业务侧自己的心跳或序列号连续性来判断,两者对不上时以业务侧为准。
6. 版本差异与验收闭环:用第三版标准做一次可复现的冗余网络验证
第三版(2016-03)相对上一版的变化,从目录结构上能直接看出来:HSR 侧补齐了 CoS、时钟同步、确定性介质访问这几节,并把 QuadBox 单独列为一节给出规范。这几处补充不是文字修饰,它们对应的正是环网规模上去之后必然遇到的三个问题——流量分级、同步精度、访问确定性。拿着一份第二版的旧材料做 HSR 环网设计,很容易在这三块上留下空白,等现场出现同步抖动或突发丢包时才发现没有依据可查。
真正把这份标准用起来的标志,是能拿出一份可复现的验收记录,而不是读完了事。我一般按下面这张表走一遍,每一项都要有对应的抓包文件或日志,不接受「看起来正常」这种结论:
| 验收项 | 判据 | 取证方式 |
|---|---|---|
| 两个 LAN 物理隔离 | 两侧 MAC 地址表无交集 | 交换机 MAC 表导出比对 |
| 复制点位置正确 | 两个端口同一帧的序列号一致 | 双口抓包 + 序列号集合比对 |
| 去重生效 | 应用层收到的数据无重复 | 业务侧序列号连续性检查 |
| 监督机制存活 | NodesTable 全部节点在一个周期内更新 | 定期导出节点表 |
| 冗余降级可见 | 单口故障时节点表能反映出来 | 故障注入 + 节点表对比 |
| 故障切换无感 | 业务侧零中断或仅有实现引入的瞬断 | 长时间高频探测 + 抓包时间对齐 |
| 环网容量有余量 | 最坏路径跳数下的时延与吞吐达标 | 逐跳实测,不用理论值代替 |
这张表里最容易被跳过的是第四项和第五项。前五项都是「通不通」的问题,后两项是「坏了知不知道」的问题。现场真正的血泪经验往往来自后者:网络一直好好的,直到某天断了一根线,才发现冗余其实早就降级了,只是没人看过节点表。
还有一点关于版本核对。这份标准的封面版本号、发布年月、以及正文里对上一版变更的说明,是确认手上材料的唯一依据。第三版和更早版本在 HSR 的帧处理和互联规范上有实质差别,混用会直接导致两端设备对不上。从那以后我每次拿到一份标准文档,第一件事都是翻到变更说明那一节,确认它相对上一版动了哪些条款,再去对现场设备的实现版本——这个习惯替我挡掉过好几次「按标准做的但就是不通」的扯皮。希望帮到你。
本文还有配套的精品资源,点击获取