QoS 与消息投递
MQTT 提供三种 Quality of Service:在开销与可靠性之间折中
规范表述(5.0):At most once / At least once / Exactly once
1. 三种 QoS
| QoS | 名称 | 保证 | 可能结果 | 典型场景 |
|---|---|---|---|---|
| 0 | At most once | 尽力投递 | 可能丢失 | 高频传感器、可丢一帧 |
| 1 | At least once | 必达 | 可能重复 | 命令、告警、多数业务 |
| 2 | Exactly once | 仅一次 | 握手最重 | 计费、关键状态机(慎用) |
OASIS 说明摘要:QoS0 可丢;QoS1 保证到达但可重复;QoS2 保证恰好一次。
2. 握手过程
QoS 0
1 | Sender ──PUBLISH──▶ Receiver |
无确认。最快、最省。
QoS 1
1 | Sender ──PUBLISH (Packet ID)──▶ Receiver |
超时重传 PUBLISH → 接收方可能收到重复 → 应用需幂等。
QoS 2
1 | Sender ──PUBLISH──▶ Receiver |
四步握手,存储与往返最多,延迟与复杂度最高。
3. “端到端”到底保证到哪?
重要澄清:
- QoS 是 MQTT 协议端(Client↔Broker 或转发路径上的协议跳) 的保证
- 发布端到订阅端通常是 两段:Publisher→Broker、Broker→Subscriber
- 最终有效 QoS 受两段中的约束影响(实现会取合适等级)
因此:
- 选 QoS2 不等于业务绝对“全局恰好一次”
- 分布式系统仍常需业务幂等键 / 去重
4. 如何选择(实用)
| 场景 | 建议 |
|---|---|
| 关节状态 50Hz 遥测 | QoS0 或 QoS1 + 可接受重复 |
| 模式切换 / 急停命令 | QoS1 + 幂等命令 ID |
| 计费/库存扣减 | QoS1/2 + 强幂等(别只靠 QoS2) |
| 弱网手机 | QoS1 + 会话恢复,观察重传风暴 |
经验:大多数业务用 QoS1 + 幂等 比全面 QoS2 更稳。
5. 重复与乱序
- QoS1 重传 ⇒ 重复交付
- 多订阅、桥接、集群 ⇒ 可能看到乱序(相对单一流)
- Payload 应带:
seq/timestamp/message_id
6. 流控相关(MQTT 5)
MQTT 5 引入更明确的流控属性,例如:
- Receive Maximum
- Maximum Packet Size
- Topic Alias Maximum
避免发送方打爆接收方;详见 04-MQTT5新特性.md。
7. 与 ROS 2 DDS QoS 对照(帮助选型)
| MQTT | 近似 DDS 直觉 |
|---|---|
| QoS0 | BEST_EFFORT |
| QoS1 | RELIABLE + 可能重复 |
| Retain | 有点像 TRANSIENT_LOCAL 的“晚加入拿到最后状态” |
| Session | 不同于 DDS History;是协议会话状态 |
二者不是一一映射;桥接时要显式设计丢失/重复策略。
下一篇:04-MQTT5新特性.md
正在加载留言…