集成 · Broker

把 OPC UA 接入 Mosquitto / MQTT 代理

产品Mosquitto / MQTT broker
类别代理
OPC UA 角色网关

Mosquitto 完全不讲 OPC UA。在常见架构中,它是北向传输:由 OPC UA 客户端或 OPC UA PubSub publisher 把机器数据映射到 MQTT 主题上。真正重要的设计决策是主题层级、负载编码,以及你对事件所接受的服务质量等级。

开始之前

  • 某个真正会说 OPC UA 的东西:一个发布方、一个采集器或一个网关。代理是目的地而不是客户端,任何代理配置都不会让 PLC 自己发布。
  • 在第一个主题出现之前就要决定负载格式。OPC UA PubSub over MQTT 搭配 JSON 是基于标准的路线;采集器自有的 JSON 结构和 Sparkplug B 是常见的替代方案,而它们并不可互换。
  • 一套与消费方商定的主题命名规范,因为主题树就是契约,之后重命名会同时破坏每一个订阅者。
  • 在任何生产数据发布之前就配置好带真实证书的 TLS 和身份验证。工厂网络上一个开放的 broker 就等于一个开放的工厂。

配置方法

  1. 先为 broker 配置 TLS 和身份验证设置明确的 listener,禁用匿名访问,配置凭据或客户端证书,并按客户端添加主题访问控制。在任何 publisher 出现之前做好这些,比日后在一批 publisher 上补做要容易得多。
  2. 从工厂出发设计主题层级,而不是从地址空间出发机械地由 OPC UA 浏览路径派生出来的主题树很省事,却会产生没人能有效订阅的主题。应当从工厂、区域、产线和设备出发派生,再把信号名称放在叶子节点上。如果发布方确实支持按浏览名自动路由,要知道 MQTT 保留字符必须转义,并确认发布方是如何处理它们的。
  3. 选定并固定负载编码如果你在 MQTT 上使用 OPC UA PubSub,需要在 UADP 和 JSON 之间做出选择;若选 JSON,还要在可逆和不可逆形式之间选择。不可逆 JSON 会丢失类型信息且无法往返还原,这个意外往往在数月之后才在下游消费端出现。
  4. 按主题类别决定保留消息和遗嘱消息保留消息让新订阅方立即拿到当前值,这对状态和标识是对的,对事件则是错的:保留消息会重放一件已经发生过的事。为每个发布方配置一个遗嘱主题,这样采集器掉线时是可见的。
  5. 让服务质量与数据的含义相匹配对于反正要重采样的高频模拟量,QoS 0 没问题;但对于停机事件或计数增量则不可接受,因为一次网络抖动就会把它丢掉。凡是计算所依赖的数据都使用至少一次投递,并让消费端具备幂等性。
  6. 在构建消费者之前用客户端验证负载用 MQTT Explorer 或命令行客户端订阅,读取线路上真实的字节。特别要注意,在 OPC UA JSON 编码中 Good 状态是零值并会被省略,因此缺少状态字段意味着状态良好,而不是数据缺失。
  7. 分别监控 broker 和 publisher关注 broker 的连接数和丢弃的消息数,并通过 last-will 主题或每台机器一个心跳主题对 publisher 的存活状态告警。主题上的静默是有歧义的,需要一个独立信号来解读。

地址空间是什么样子

MQTT 没有模型,只有一个主题字符串和一个负载,因此 OPC UA 地址空间中原有的一切都必须由发布方重新表达。这正是统一命名空间的核心设计决策:对所有消费者而言,主题层级加上负载 schema 就是全部的信息模型。OPC UA PubSub 会随数据一起携带数据集元数据,从而保留类型和字段名称,这也是基于标准的路径值得付出额外配置工作的原因;临时拼凑的采集器输出的 JSON 通常不携带这些信息,字段的含义就只能存在于某份文档里。无论选择哪一种,都要把 OPC UA 命名空间 URI 和节点标识符放进负载或主题元数据中,这样一个数值才能追溯回它来自的节点。

陷阱

  • 把 broker 当成集成本身是典型错误。broker 只搬运字节;语义来自 publisher 的主题和负载设计,而这套设计才是项目的真正工作量所在。
  • 对事件类数据使用 QoS 0,恰恰会在产生最值得关注的事件的那种网络状况下静默丢失事件。停机记录和计数增量需要至少一次投递。
  • 事件主题上的保留消息会把陈旧事件重放给每个新订阅者,这会破坏那些认为收到消息就意味着“此刻”的消费方。
  • 非可逆 JSON 编码会丢失类型信息,无法往返还原。请有意识地做出选择并记录下来;在下游才发现代价很高。
  • 在 OPC UA JSON 编码中,Good 状态为零并被省略,因此把缺失的状态字段当作数据缺失的消费方会丢弃正常的值。
  • 由浏览路径自动生成的主题树,会把 PLC 的内部结构编码进你的全厂命名空间,而且 PLC 程序一改它们就会变。
  • broker 会成为全厂的单点故障和全厂的安全边界。要么做集群,要么明确接受这一风险,并且绝不要因为调试期间方便就一直开着匿名访问。
  • MQTT 不保证跨不同主题的顺序。如果状态变化和与之对应的计数发布在不同主题上,它们可能乱序到达,因此请把必须保持一致的事实放在同一条消息里。

从中获取 OEE 数据

broker 本身对 OEE 毫无贡献,还可能悄悄损害它。它擅长的是把采集与计算解耦,让分析平台无需对每台 PLC 保持会话就能消费设备状态、计数和原因。它提出的要求很具体:把状态迁移作为事件发布,负载中带设备自身的时间戳,而不是依赖到达时间;发布计数增量或绝对计数器,并带足够的上下文以便识别复位;两者都使用至少一次投递;给每台设备一个心跳或遗嘱主题,使静默可以与停机区分开。计划生产时间、班次日历、订单上下文和标准节拍时间不是设备数据,应当从 MES 或 ERP 到达计算环节,而不是手工发布到某个主题上然后被遗忘。

在依赖它之前请先核实:Broker 的配置语法、TLS 与认证选项以及访问控制文件格式,在 Mosquitto 各版本之间以及不同 broker 之间都有差异,因此请查阅你所部署版本的配置参考。在 OPC UA 侧,你的 publisher 支持哪些 PubSub 传输、编码和安全密钥机制,属于该产品及版本的特性,在围绕它设计主题和负载约定之前,必须查阅其自身的当前文档加以确认。

最后核对日期 2026 年 9 月 7 日,对照 OPC UA 1.05.07。OPC UA Connect 是教育资源,与 OPC Foundation 无隶属关系。

免费下载
OPC UA Machine Data → OEE Mapping Kit
该订阅哪些节点、它们如何变成可用率、性能和质量,以及哪一个伴随规范已经给出了答案:从此不必再自己发明标签。
获取免费映射工具包 →
免费,无需课程,无需登录