简要回答

好的消息契约标识来源、时间、模式和意图,同时将业务事件与原始遥测区分开来。

实践要点

  • 事件 ID 支持去重。
  • 设备时间可能不确定。
  • 命令需要确认和最终结果。

推荐方法

  1. 使用显式的模式版本。
  2. 保持信封精小且一致。
  3. 在生产者和消费者边界处校验。

边界与失败模式

  • 用一个 data 消息承载所有意图。
  • 依赖字段顺序。
  • 将代理投递视为命令完成。

范围与消息分类

将遥测、事件、命令、确认和状态分开。遥测是带有值、单位、质量、源时间和序列号(如有)的观测数据。事件是带有稳定 ID 和类型的不可变离散发生。命令是请求执行一个动作,带有 ID、目标、参数、过期、前置条件和发起方上下文。确认报告已接受、已拒绝、已开始、已完成、已失败、已过期或已被替代。状态是带有新鲜度的版本化当前视图。

此模型覆盖应用负载,不覆盖认证、传输保证或传感器精度。

信封与时间语义

使用精小的信封,包含消息 ID、类型、来源、发生时间、序列范围、模式标识和数据。说明时间来自设备、网关还是平台。单独保留接收时间。当值可能超出消费者的整数精度时使用字符串标识符。将可变的客户标签保留在注册表中,而非复制到每条设备消息中。

传输元数据在消息处于单跳时可以保持传输特定,但在网桥或存储后需要保留的字段必须保留。绝不能将 MQTT 报文标识符用作业务幂等键。

演进规则

优先使用带文档化默认值的可选附加字段。消费者仅在安全时才可忽略未知字段。绝不能原地更改类型、单位或含义。破坏性变更需要新的模式标识和共存计划。主题版本和负载版本解决不同的契约。

在版本控制中维护模式、有效示例和无效反例。在 CI 中对每个支持的生产者与消费者进行测试。在入口处校验并保留有限的、脱敏的拒绝证据。

实施步骤

  1. 盘点流并分类消息类型。
  2. 定义标识符、时间、序列、单位、质量和生命周期。
  3. 根据设备约束和生态支持选择编码格式。
  4. 编写模式和示例。
  5. 定义兼容性和弃用策略。
  6. 为事件和命令添加幂等性和关联。
  7. 在 CI 中测试生产者、网关和消费者。
  8. 观察版本、校验失败、重复和延迟。
  9. 演练混合版本、重放、重启和时钟丢失。

失败模式

没有单位的温度值是歧义的。设备时钟可能倒退。重试时生成新的命令 ID 会破坏幂等性。超时时发布零值会破坏缺失数据的含义。将未知枚举值视为成功会使附加演进不安全。通过 JavaScript 数值转换的二进制整数可能丢失精度。重写时间戳的网关会破坏溯源。

实施清单

  • 消息类别有独立的契约。
  • 标识、时间、单位、质量、序列和模式明确。
  • 命令包含 ID、过期、前置条件和结果。
  • 缺失值保持可区分。
  • 禁止原地语义变更。
  • 模式和兼容性测试在版本控制中。
  • 被拒绝和未知版本可观测。
  • 混合版本和重复测试通过。

治理与验证证据

为每个模式指定负责人并发布其兼容性承诺、支持版本、保留期和移除日期。注册表条目应将模式链接到生产者、消费者、主题或端点、示例和变更历史。代码生成可以减少拼写错误但不能决定语义;评审者仍需检查单位、可空性、枚举演进、隐私以及缺失字段的含义。

构建一个契约测试套件,包含来自每个支持的固件和网关的黄金消息。将它们通过校验、存储、分析、规则、导出和命令处理程序运行。添加格式错误长度、未知枚举值、额外字段、缺失可选和必填值、重复 ID、时钟回退、序列重置、乱序到达和数值边界值。在滚动部署中旧新生产者和消费者共存时验证行为。

保留按原因分类的拒绝消息证据、版本采用率、未知字段、重复抑制、时钟偏差和消费者延迟,并对负载脱敏和有限保留。如果网关在测量前静默丢弃错误输入,百分之百的校验成功率可能是可疑的。追踪一条消息从设备观测到业务结果,同时保留标识、时间戳、质量和关联。仅在流量归零、保留或排队的副本过期、且授权或路由规则不再接受旧版本时才退役旧版本。

文档化语义转换的归属。当网关更改单位、聚合采样、填充值或映射厂商枚举时,输出必须标识该转换及其版本。否则下游消费者会将派生数据错误地归因于原始设备。

主要参考来源

CloudEvents 规范是有用的事件信封参考。MQTT 5.0定义了传输属性、过期和关联数据。JSON 契约可使用 JSON Schema 2020-12;二进制格式应遵循其规范性模式规范。