第 1 章 · 03 服务质量 QoS 与主题


文档摘要

第 1 章 · 03 服务质量 QoS 与主题 本节摘要:QoS 与主题是 MQTT 的两个核心概念,贯穿所有后续章节。QoS(服务质量)定义了消息送达的三档语义:最多一次/至少一次/仅一次;主题则定义了消息的"地址系统"。本节先把这两个概念讲透,顺带介绍两个特殊消息机制——遗嘱消息与保留消息,它们都是后续报文详解里的常客。 学习目标 阅读完本节,你应当能够: 说出 QoS 0/1/2 三档的语义与典型场景。 解释 QoS 的协商规则(发布者定 QoS,订阅者用最大 QoS 上限)。 理解主题的层级结构、分隔符、 前缀约定。 说出遗嘱消息与保留消息的作用。

第 1 章 · 03 服务质量 QoS 与主题

本节摘要:QoS 与主题是 MQTT 的两个核心概念,贯穿所有后续章节。QoS(服务质量)定义了消息送达的三档语义:最多一次/至少一次/仅一次;主题则定义了消息的"地址系统"。本节先把这两个概念讲透,顺带介绍两个特殊消息机制——遗嘱消息保留消息,它们都是后续报文详解里的常客。

学习目标

阅读完本节,你应当能够:

  1. 说出 QoS 0/1/2 三档的语义与典型场景。
  2. 解释 QoS 的协商规则(发布者定 QoS,订阅者用最大 QoS 上限)。
  3. 理解主题的层级结构、分隔符、$ 前缀约定。
  4. 说出遗嘱消息与保留消息的作用。

一、服务质量 QoS:三档送达语义

QoS(Quality of Service)是 MQTT 最核心的概念,定义了发布者与服务端之间服务端与订阅者之间消息分发的保证级别。三档语义:

QoS 名称 语义 确认机制 典型场景
0 最多分发一次(At most once) 尽力而为,可能丢失 无确认 传感器高频遥测、日志,丢了下一帧补
1 至少分发一次(At least once) 保证送达,但可能重复 PUBACK 确认 + 重发 命令下发,客户端需做幂等
2 仅分发一次(Exactly once) 保证送达且不重复 四步握手(PUBREC/PUBREL/PUBCOMP) 计费、支付等不可重复处理的消息

三个要点:

  1. QoS 是"端到端分段"的:发布者→服务端 按发布 QoS 处理;服务端→每个订阅者 按订阅请求里的 QoS 处理(服务端可以降级转发,但不能升级)。所以同一条消息,不同订阅者可能以不同 QoS 收到。
  2. QoS 1/2 的重发依赖报文标识符(Packet Identifier):只有 QoS > 0 的报文才有报文标识符,服务端据此识别重发。
  3. QoS 2 的代价是开销:一次 QoS 2 发布需要 4 个报文往返,吞吐低于 QoS 1。选档要权衡可靠性与成本。

💡 第 4 章会用时序图逐帧拆解 QoS 1/2 的完整流程,这里先记住语义即可。

二、主题:消息的地址系统

主题(Topic) 是应用消息上的一个字符串标签,服务端据此决定把消息转发给谁。主题有几个关键性质:

  • 层级结构:主题由 / 分隔成多级,例如 house/room1/temperature。层级让主题天然可组织、可管理。
  • 发布时不能带通配符:发布者发布到 house/room1/temperature 这样具体的主题;通配符只在订阅过滤器里使用。
  • $ 前缀保留:以 $ 开头的主题(如 $SYS/broker/uptime)是服务端保留的系统主题。通配符 #/+ 开头的过滤器不会匹配 $ 开头的主题——这是规范明确的行为(细节见第 4 章)。

主题过滤器支持两级通配:

通配符 含义 示例
+ 单层匹配 house/+/temperature 匹配 house/room1/temperaturehouse/room2/temperature
# 多层匹配(必须放末尾) house/# 匹配 househouse/room1house/room1/temperature

⚠️ 常见误区:house/# 匹配 house 本身(规范允许"父级"匹配);但 # 不能匹配 $SYS/...

三、两个特殊消息:遗嘱与保留

遗嘱消息(Will Message)

客户端可以在 CONNECT 里声明遗嘱:指定一个遗嘱主题、遗嘱消息内容与 QoS。之后如果客户端非正常断开(网络异常、超时未心跳、协议错误),服务端会代替客户端发布这条遗嘱消息,通知其他订阅者"它掉线了"。

  • 遗嘱消息只在异常断开时发布;客户端主动发送 DISCONNECT 优雅退出时,不会发布遗嘱。
  • 遗嘱的传输沿用 QoS 与保留标志(见下)。

💡 这是物联网场景的杀手锏:设备掉线是常态,服务端代发遗嘱让监控系统能立刻感知设备失联。

保留消息(Retained Message)

发布者在 PUBLISH 里把 Retain 标志置 1,服务端就会保存这条消息作为该主题的"当前状态"。之后任何新订阅者订阅该主题时,服务端立即把这条保留消息推给它,而不必等下一次发布。

  • 保留消息的典型用途:设备状态、传感器最新值、配置信息——新订阅者"一上来就知道当前状态"。
  • 要清除保留消息,只需向该主题发布一条 Retain=1 且负载为空(0 字节) 的消息。

小结

QoS 解决"消息怎么可靠送达",主题解决"消息发给谁"。再加上遗嘱(异常感知)与保留(状态缓存),MQTT 的应用层语义就齐了。接下来进入协议底层:第 2 章拆解所有控制报文的通用格式。


发布者: 作者: 灏天文库 转发
评论区 (0)
U