直接回答

使用满足单跳网络失败模型的最低 MQTT QoS,然后将应用设计为仍然可能发生重复、延迟、乱序和数据丢失。QoS 0 适合很快被更新采样值替代的数据。QoS 1 是丢消息有影响且重复处理安全的实用默认选择。QoS 2 仅在其两阶段交换能解决已测量的跳级问题时才值得使用;它不能实现业务层面的精确一次处理。

范围与边界

本指南覆盖一个 MQTT 客户端与一个代理之间的投递,以及将发布转发给订阅者的后果。它不能证明传感器采样正确、订阅者提交了事务或执行器完成了命令。这些结果需要应用层确认、持久状态和超出 MQTT QoS 范围的对账机制。

QoS 在每个投递段上独立选择。发布者可以以 QoS 1 发送,而订阅者以 QoS 0 接收,因为投递使用发布 QoS 和订阅最大 QoS 中的较低值。保留消息、持久会话、消息过期和代理队列策略也会影响重连订阅者收到的内容。

决策准则

从丢失一条消息的后果开始分析。频繁采样的周期性温度遥测通常可以容忍丢失一个采样,因为下一个值会取代它。状态转换如“泵进入故障”可能需要 QoS 1、持久消费和事件标识符,因为后续读数无法保留转换信息。安全工作流可能需要应用事务和明确的结果确认;仅选择 QoS 2 是不够的。

然后评估重复代价。QoS 1 在确认丢失时故意允许重投。在负载中放入稳定的事件或命令标识符,并让消费者据此记录完成状态。不要将 MQTT 报文标识符用作业务键:它们的作用域仅限于网络会话,且可能被重用。

最后考虑链路和恢复路径。QoS 1 增加确认并在确认前保持发布在途。QoS 2 增加 PUBREC、PUBREL 和 PUBCOMP 状态。在有损蜂窝网络上,这些状态会增加空口时间并延长恢复周期。使用实际客户端和代理测量在途窗口、重传行为、队列限制和消息过期。

工作负载 起始选择 附加控制
高频可替代遥测 QoS 0 序列号和新鲜度限制
必须到达平台的离散事件 QoS 1 幂等事件处理
设备命令 QoS 1 命令 ID、过期、确认和结果状态
有严格跳级重复约束的中继 评估 QoS 2 证明确切收益和状态成本

实施步骤

  1. 将每条消息分类为可替代状态、持久事件、命令、确认或批量传输。
  2. 在分配 QoS 之前写下丢失和重复的后果。
  3. 添加事件或命令标识符,在不允许重复副作用的地方建立幂等存储。
  4. 设置消息过期,使过期的排队遥测和命令不会在有效窗口之后执行。
  5. 限制客户端和代理的在途消息数、离线队列和重试时间。
  6. 在每个协议确认前后测试连接丢失,而非仅测试正常投递。
  7. 分别观察发布确认、重投递、过期消息、队列时长和消费者完成情况。

需要测试的失败模式

QoS 1 消费者如果在每次投递时递增计数器,重投后会计数过多。设备如果在持久化命令 ID 之前执行命令,重启后可能重复物理动作。持久订阅者重连到大量积压消息后可能处理过期命令,除非消息设置了过期。发布者可能收到 PUBACK 时下游业务服务不可用,因为代理接收不等于应用完成。QoS 2 在数据离开 MQTT 进入数据库或其他代理后仍可能重复操作。

测试代理重启、客户端有/无持久会话状态的重启、确认丢失、在途窗口耗尽、队列溢出和消息过期后的重连。同时记录链路投递和最终业务结果。

实施清单

  • 每个消息类别都有明确的丢失和重复策略。
  • 消费者使用稳定的应用标识符实现幂等性。
  • 命令具有过期、确认和结果语义。
  • 在途和离线队列有文档化的限制。
  • 会话过期与产品的离线预期匹配。
  • 失败测试覆盖每个确认阶段的断连。
  • 指标区分代理接收与业务完成。

主要参考来源

MQTT 5.0 第 4.3 和 4.4 节定义了 QoS 流程和投递行为。第 3.3、3.8 和 4.1 节描述了发布、订阅最大 QoS 和会话状态。使用 OASIS MQTT 5.0 规范作为规范性参考,然后在所选代理和客户端文档中验证持久化和队列行为。