2. 工业数据通信基础

Sparkplug B 并不是一套全新的传输协议,它建立在 MQTT 3.1.1 / 5.0 之上,是对 MQTT 的“语义增强层”。要理解 Sparkplug B 为什么这样设计主题、为什么强制使用 QoS 1、为什么规定出生消息与死亡消息,就必须先回到 MQTT 本身的四个核心概念:客户端与代理、发布订阅模式、QoS 等级、主题与通配符。本节把这四个概念与 Sparkplug B 的约束逐一对齐,帮助你在后续建模时知道每一条规范背后的通信原因。

一、核心原理:从客户端/代理到发布订阅

MQTT 采用典型的客户端—代理(Broker)架构。所有设备、网关、SCADA、边缘计算节点都是客户端,它们不直接互相连接,而是统一连接到 Broker。客户端分为两类角色:发布者(Publisher)把消息发布到某个主题,订阅者(Subscriber)通过订阅主题来接收消息。Broker 负责主题匹配与消息转发,是整个通信的枢纽。

发布订阅模式的关键在于“解耦”:

  • 空间解耦:发布者不知道也不关心谁在订阅,只认主题。
  • 时间解耦:发布者发送时订阅者可以不在线,是否保留消息由 Retain 标志决定。
  • 数量解耦:一个主题可以被任意多个订阅者同时订阅,天然支持一对多分发。

Sparkplug B 正是利用这种解耦,让现场设备只负责“上报数据”,而 SCADA、MES、历史库各自订阅自己关心的主题,无需设备端做点对点配置。这也是工业物联网中“设备一次接入、多系统消费”的基础。

关键对应:Sparkplug B 的 Topic Namespace 就是 MQTT 主题的规范化约定,它把“谁、在哪、是什么、什么类型”编码进主题层级,使 Broker 的纯字符串匹配具备工业语义。

二、QoS 等级:Sparkplug B 为什么强制 QoS 1

MQTT 定义了三个服务质量等级,决定了消息投递的可靠性与开销:

QoS 投递语义 交互过程 Sparkplug B 使用情况
QoS 0 至多一次,可能丢失 PUBLISH 后不确认 不用于关键数据
QoS 1 至少一次,可能重复 PUBLISH → PUBACK 规范要求用于 STATE、NDATA、DDATA 等
QoS 2 恰好一次,开销最大 四次握手 Sparkplug B 不要求,通常不用

Sparkplug B 规定数据消息使用 QoS 1,原因是工业现场更怕“丢”而不是“重”。QoS 1 通过 PUBACK 确认保证消息至少到达一次,配合消息中的序列号(seq)和 BD 序列(bdSeq),接收端可以识别重复并去重。QoS 2 虽然语义更强,但四次握手会显著增加延迟和 Broker 负担,对高频遥测不划算。因此 Sparkplug B 选择“QoS 1 + 序列号去重”的组合,在可靠性与实时性之间取得平衡。

实践提示:如果现场出现数据重复,不要急着把 QoS 降到 0,而应检查接收端是否按 seq 做了去重。降 QoS 会直接破坏 Sparkplug B 的可靠性前提。

三、主题通配符与 Sparkplug B 主题结构

MQTT 主题使用斜杠分层,并支持两种通配符:+ 匹配单层,# 匹配多层且只能出现在末尾。Sparkplug B 的主题命名空间正是建立在这套分层规则之上:

spBv1.0/<group_id>/<message_type>/<edge_node_id>/<device_id>

示例:
spBv1.0/LineA/NDATA/PLC01
spBv1.0/LineA/DDATA/PLC01/TempSensor
spBv1.0/LineA/STATE/SCADA01
spBv1.0/LineA/NBIRTH/PLC01

其中 message_type 包括 NBIRTH、NDEATH、NDATA、DBIRTH、DDEATH、DDATA、STATE 等。SCADA 端可以用通配符一次性订阅整条产线:

spBv1.0/LineA/#
spBv1.0/+/NDATA/+
spBv1.0/LineA/DDATA/PLC01/+

但要注意:# 订阅范围过大时,会把出生、死亡、状态、数据全部收进来,接收端必须按 message_type 分流处理。Sparkplug B 规范建议按需订阅,避免无关流量冲击边缘网关。

四、案例场景:一条产线的数据流

假设 LineA 产线有一台 PLC01,下挂 TempSensor 设备,SCADA01 负责监控。通信过程如下:

  1. PLC01 上线,向 spBv1.0/LineA/NBIRTH/PLC01 发布出生消息,声明自身指标与设备清单。
  2. TempSensor 通过 PLC01 发布 spBv1.0/LineA/DBIRTH/PLC01/TempSensor,声明测点。
  3. 正常运行时,PLC01 周期性发布 spBv1.0/LineA/NDATA/PLC01,携带 seq 与指标值。
  4. SCADA01 订阅 spBv1.0/LineA/#,接收并解析所有消息。
  5. 若 PLC01 异常断开,Broker 依据遗嘱消息发布 spBv1.0/LineA/NDEATH/PLC01,SCADA01 立即感知设备离线。

这条链路中,QoS 1 保证 NDATA 不丢,通配符让 SCADA 一次订阅整线,出生/死亡消息让状态可追踪,三者共同构成 Sparkplug B 的“可发现、可确认、可去重”通信基础。

五、误区与复盘

常见误区一:把 Sparkplug B 当成独立协议去实现,忽略底层仍是 MQTT。结果自定义主题、自定义 QoS,导致与标准 SCADA 无法互通。

常见误区二:用 QoS 0 发送 NDATA,认为“丢一两个点没关系”。但 Sparkplug B 的 seq 连续性依赖可靠投递,丢包会造成序列断裂,接收端误判设备异常。

常见误区三:滥用 # 订阅,把整个 Broker 的所有主题都收进来,造成网关 CPU 与带宽浪费。

复盘要点:先确认 Broker 支持 MQTT 3.1.1 及以上;再确认所有数据消息使用 QoS 1;然后检查主题是否符合 spBv1.0/group/message_type/node/device 五层结构;最后验证出生、死亡、状态消息是否齐全。只有这四步都通过,Sparkplug B 的数据模型才有可靠的通信底座。

MQTT 发布订阅模型与 Sparkplug B 主题映射 MQTT Broker 主题匹配 · 消息转发 · 会话保持 PLC01(发布者) NBIRTH / NDATA / NDEATH QoS 1 · seq 递增 SCADA01(订阅者) 订阅 spBv1.0/LineA/# 按 message_type 分流 TempSensor(设备) DBIRTH / DDATA / DDEATH PUBLISH 转发 DDATA Sparkplug B 主题命名空间(五层结构) spBv1.0 group_id message_type edge_node_id device 示例:spBv1.0 / LineA / NDATA / PLC01 通配符订阅:spBv1.0/LineA/# 或 spBv1.0/+/NDATA/+ QoS 1 保证至少一次投递,seq 用于接收端去重

把 MQTT 的四个基础概念与 Sparkplug B 的规范逐条对应后,你会发现 Sparkplug B 的每一条约束都不是凭空规定:主题命名空间来自 MQTT 分层主题,QoS 1 来自工业可靠性需求,出生/死亡消息来自 Retain 与遗嘱机制,序列号来自 QoS 1 的重复投递特性。理解这层关系,后续学习 NBIRTH、NDATA、DBIRTH 等消息类型时,就能从通信机制出发判断每条字段存在的意义。