前言
本文基于 MQTT v5.0 编写。
什么是MQTT协议?
MQTT 全称 Message Queuing Telemetry Transport,即消息队列遥测传输。它是基于发布/订阅模式的轻量级消息传输协议,专为资源受限的设备和低带宽、高延迟或不可靠的网络设计,广泛应用于物联网(IoT)、工业控制、智能家居监控等领域。
MQTT如何工作?
MQTT工作原理
核心概念
MQTT客户端
运行 MQTT 客户端程序的应用或设备。例如,通过 MQTT 协议上报数据的智能手表。
MQTT Broker
负责管理客户端连接、消息分发、主题的订阅/取消订阅。
MQTT主题
MQTT 协议基于主题(TOPIC)进行消息分派。主题通过 / 来定义层次结构,类似于文件路径,如:
news/sport
devices/deviceId/humidity
主题通配符
多级通配符(#)
符号 # 是一个多层通配符,可以匹配主题中任意数量的层次。例如:
- "#" 将收到应用的每条消息。
- "devices/#" 将收到使用以下主题发布的消息:
- "devices"
- "devices/001/humidity"
- "devices/001/data/humidity"
其中,需要注意多级通配符必须单独使用或者跟在最后一级分隔符之后。例如,下述均为无效主题:
- "news/message#"
- "news/message/#/music"
单层通配符(+)
符合 + 是一个单层通配符,可以匹配主题中的单个层次。例如:
- "+" 将收到使用单层主题发布的消息:
- "devices"
- "news"
- "devices/+/humidity" 将收到使用以下主题发布的消息:
- "devices/001/humidity"
- "devices/002/humidity"
以 $ 开头的主题
通常用作发布系统消息的主题。比如:
- "sys/status/cpu"
需要注意的是,服务器通配符不会为以通配符("#","+")开头的主题过滤器匹配以 "$" 开头的主题。
MQTT订阅
MQTT提供两种订阅方式:
- 普通订阅:订阅同一主题的每个客户端都可以接收到使用该主题发布的消息。
- 共享订阅:订阅同一主题的多个客户端仅有其中一个客户端能够收到使用该主题发布的消息,即消息会在多个订阅者之间负责均衡分发。
共享订阅(MQTT v5.0新增功能)
共享订阅使用的主题过滤器格式如下:
$shared/{sharedName}/{filter}
其中:
- $shared 是一个固定的前缀,代表该主题过滤器是个共享主题过滤器。
- {shareName} 是一个不包过通配符("#" 和 "+")的字符串。
- {filter} 的语法和普通主题一样。
例如,"$share/worker/sensor/data/+"。
消息服务质量(QoS)
MQTT根据下面定义的服务质量级别交付应用程序消息:
- QoS 0:消息的分发依赖于网络质量。接收方不发送响应,发送方也不作重试。
- QoS 1:保证消息至少到达接收方一次。
- QoS 2:最高级别的服务等级,保证消息只到达接收方一次。
QoS 2 四次握手
Publisher -------- PUBLISH(msgId: 19) --------> MQTT Broker
Publisher <-------- PUBREC(msgId: 19) --------- MQTT Broker (Store message)
Publisher -------- PUBREL(msgId: 19) ---------> MQTT Broker
Publisher <-------- PUBCOMP(msgId: 19) -------- MQTT Broker (Discard message)
服务质量对比
| 服务质量 | 开销 | 使用场景 |
|---|---|---|
| QoS 0 | 最低 | 允许消息丢失的情况。 |
| QoS 1 | 中 | 消息不能丢失但允许重复接收。 |
| QoS 2 | 最高 | 严格要求消息不能丢失且不可重复接收的情况,如金融交易场景。 |
保留消息(Retained Message)
当客户端订阅一个主题时,会立即收到该主题的“最后一条保留消息“。
工作机制:
- 客户端发布消息时,将
retain标志位置1。 - MQTT Broker 会保存该消息及其主题(只保存每个主题最后一条保留消息)。
- 有新的客户端订阅该主题时,MQTT Broker 会立即把这条消息分发给它。
- 如果发布一条
retain = 1的空消息(空载荷),表示清除该主题的保留消息。
遗留消息(Will Message)
当客户端异常断开时,MQTT Broker 会自动帮它发布一条预设的消息,用于通知其他客户端它“死了”。
工作机制:
- 客户端在发送 CONNECT 报文时,在其载荷中携带 Will 消息。
- 如果客户端正常断开,MQTT Broker 不会发布遗言。
- 如果客户端异常断开,MQTT Broker 在检测到连接断开后,会帮它发布 Will 消息。
典型应用场景
- 智能家居:温度传感器发布数据到 MQTT Broker。
- 车联网:车辆发布GPS数据到 MQTT Broker。
性能优化建议
- 低功耗设备:使用QoS 0减少通信开销
- 高价值数据:使用QoS 2确保精确一次交付
- 高频数据:考虑使用共享订阅进行负载均衡
总结
MQTT 协议的发布/订阅模式实现了应用间的解耦、消息的实时传输与处理。这种”解耦 + 实时“的双重特性,使其成为物联网、实时通讯等场景的优先协议。