深入理解入门MQTT协议
文章目录
- 深入理解入门MQTT协议
-
- 一、介绍
- [二、核心架构:发布 / 订阅模式](#二、核心架构:发布 / 订阅模式)
- 三、核心概念深度解析
-
- [3.1 主题(Topic)](#3.1 主题(Topic))
- [3.2 服务质量等级(QoS)](#3.2 服务质量等级(QoS))
- [3.3 保留消息(Retain)](#3.3 保留消息(Retain))
- [3.4 遗嘱消息(Will Message)](#3.4 遗嘱消息(Will Message))
- [3.5 会话与会话保持](#3.5 会话与会话保持)
- [3.6 心跳保活(Keep Alive)](#3.6 心跳保活(Keep Alive))
- 四、报文结构详解
-
- [4.1 固定报头(1 字节 + 剩余长度)](#4.1 固定报头(1 字节 + 剩余长度))
- [4.2 可变报头](#4.2 可变报头)
- [4.3 载荷(Payload)](#4.3 载荷(Payload))
- [五、MQTT 3.1.1 vs MQTT 5.0](#五、MQTT 3.1.1 vs MQTT 5.0)
- 六、主流实现与快速上手
-
- [6.1 常见 Broker](#6.1 常见 Broker)
- [6.2 常见客户端库](#6.2 常见客户端库)
- [6.3 快速体验(Python 示例)](#6.3 快速体验(Python 示例))
- [6.4 常见 Broker--EMQX](#6.4 常见 Broker--EMQX)
- 七、典型应用场景
- 八、最佳实践建议
一、介绍
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是一种基于发布 / 订阅模式 的轻量级消息传输协议,由 IBM 于 1999 年联合发明,现为 OASIS 国际标准。它专为低带宽、高延迟、不稳定网络中的资源受限设备设计,是物联网(IoT)领域事实上的标准通信协议。
二、核心架构:发布 / 订阅模式
MQTT 采用经典的 Pub/Sub 架构,通过第三方 Broker 实现消息的收发解耦,就像 "快递驿站" 模式:
三大核心角色:
| 角色 | 职责 | 类比 |
|---|---|---|
| 发布者 Publisher | 向指定主题发送消息的设备 / 应用 | 寄件人 |
| 订阅者 Subscriber | 订阅主题并接收消息的客户端 | 收件人 |
| Broker 代理服务器 | 接收、过滤、路由、分发消息的中间节点 | 快递驿站 |
MQTT通信模型:

三重解耦特性
- 空间解耦:发布者与订阅者无需知道对方 IP 和端口
- 时间解耦:双方无需同时在线,Broker 可暂存消息
- 同步解耦:收发互不阻塞,系统异步运行
注意:一个客户端可以同时既是发布者也是订阅者。QoS 协议是 Sender 与 Receiver 之间的约定,而非 Publisher 与 Subscriber 直接达成。
三、核心概念深度解析
3.1 主题(Topic)
主题是 MQTT 消息路由的核心依据,采用层级式斜杠分隔结构,类似文件路径:
home/livingroom/temperature
factory/area1/robot01/status
命名规则:
- 区分大小写,层级间用
/分隔 - 允许空层级(如
/home/是合法的三级主题) - 以
$开头的主题为 Broker 系统保留主题(如$SYS/),业务层请勿使用
两种通配符:
+单层通配符:匹配任意一个层级sensor/+/temperature匹配sensor/1/temperature,不匹配sensor/1/2/temperature
#多层通配符:匹配后续所有层级,必须位于末尾home/#匹配home/livingroom/temp、home/bedroom/light/status
3.2 服务质量等级(QoS)
MQTT 定义了三级消息交付可靠性,是协议最核心的特性之一:
| 等级 | 名称 | 交互机制 | 可靠性 | 适用场景 |
|---|---|---|---|---|
| QoS 0 | 最多一次At Most Once | 发完即忘,无确认 | 可能丢失 | 传感器周期性上报、非关键数据 |
| QoS 1 | 至少一次At Least Once | PUBLISH → PUBACK 二次握手 | 保证到达,可能重复 | 普通控制指令、状态上报 |
| QoS 2 | 恰好一次Exactly Once | PUBLISH → PUBREC → PUBREL → PUBCOMP 四次握手 | 保证到达且不重复 | 金融交易、关键报警、计费数据 |
QoS 降级机制 :发布者的 QoS 与订阅者的 QoS 取较小值生效。例如发布者 QoS=2,订阅者 QoS=1,则实际按 QoS=1 交付。
3.3 保留消息(Retain)
发布消息时设置 Retain = 1,Broker 会存储该主题的最新一条保留消息。当有新客户端订阅该主题时,立即收到这条保留消息,解决 "订阅后无历史数据" 的冷启动问题。
每个主题仅保存一条保留消息,新的保留消息会覆盖旧的。发送空 payload 的保留消息可清除该主题的保留消息。
3.4 遗嘱消息(Will Message)
客户端连接时可预先设置遗嘱。当客户端异常断开(未发送 DISCONNECT 报文、心跳超时),Broker 自动向指定主题发布遗嘱消息,通知其他客户端该设备离线。
典型应用:设备在线状态监控、异常掉线告警。
3.5 会话与会话保持
- Clean Session = 1(干净会话):连接断开后,Broker 立即清除该客户端的所有订阅信息和未送达消息
- Clean Session = 0(持久会话):断开连接后,Broker 保留订阅关系和 QoS 1/2 的未确认消息,客户端重连后继续投递
MQTT 5.0 进一步增加了会话过期时间(Session Expiry Interval),可精确控制会话保留时长。
3.6 心跳保活(Keep Alive)
客户端设置心跳间隔(秒),在此时间内若无数据交互,需发送 PINGREQ 心跳包,Broker 回复 PINGRESP。若 Broker 在 1.5 倍心跳时间内未收到任何数据,判定客户端离线并触发遗嘱。
四、报文结构详解
MQTT 报文采用二进制格式,结构紧凑,由三部分组成:
┌─────────────┬───────────────┬───────────┐
│ 固定报头 │ 可变报头 │ 载荷 │
│ Fixed Header│ Variable Header│ Payload │
│ 所有报文必有│ 部分报文有 │ 可选 │
└─────────────┴───────────────┴───────────┘
4.1 固定报头(1 字节 + 剩余长度)
第 1 字节高 4 位为报文类型,低 4 位为标志位:
| 报文类型 | 值 | 说明 |
|---|---|---|
| CONNECT | 1 | 客户端连接请求 |
| CONNACK | 2 | 连接确认 |
| PUBLISH | 3 | 发布消息 |
| PUBACK | 4 | QoS 1 发布确认 |
| PUBREC | 5 | QoS 2 发布收到 |
| PUBREL | 6 | QoS 2 发布释放 |
| PUBCOMP | 7 | QoS 2 发布完成 |
| SUBSCRIBE | 8 | 订阅请求 |
| SUBACK | 9 | 订阅确认 |
| UNSUBSCRIBE | 10 | 取消订阅 |
| UNSUBACK | 11 | 取消订阅确认 |
| PINGREQ | 12 | 心跳请求 |
| PINGRESP | 13 | 心跳响应 |
| DISCONNECT | 14 | 断开连接 |
| AUTH | 15 | 认证(5.0 新增) |
剩余长度字段:采用变长编码,1~4 字节,表示可变报头 + 载荷的总字节数,单报文最大支持 256MB。
4.2 可变报头
内容随报文类型变化。例如 PUBLISH 报文的可变报头包含主题名、报文标识符(QoS 1/2 时);CONNECT 报文包含协议名、协议级别、连接标志、心跳间隔等。
4.3 载荷(Payload)
真正的业务数据。CONNECT 报文的载荷包含 ClientID、用户名、密码、遗嘱主题、遗嘱内容等;PUBLISH 报文的载荷就是应用消息本体。
五、MQTT 3.1.1 vs MQTT 5.0
MQTT 3.1.1(2014)是目前最广泛部署的版本,约占 65% 市场份额;MQTT 5.0(2019)是面向大规模物联网的重大升级,新增 20+ 特性:
| 特性 | MQTT 3.1.1 | MQTT 5.0 |
|---|---|---|
| 会话管理 | CleanSession 布尔值 | 会话过期时间,秒级精确控制 |
| 原因码 | 仅 CONNACK 有 5 种 | 所有确认报文支持 40+ 细化原因码 |
| 消息属性 | 无 | 支持用户自定义键值对元数据 |
| 消息过期 | 不支持 | 可设置消息在 Broker 上的存活时间 |
| 共享订阅 | 不支持 | 原生支持多消费者负载均衡 |
| 主题别名 | 无 | 长主题映射为短整数,节省带宽 |
| 流量控制 | 无 | Receive Maximum 限制未确认消息数 |
| 请求响应 | 需自行约定 | 内置响应主题 + 关联数据机制 |
| 服务端能力发现 | 无 | 连接时可查询 Broker 支持的能力 |
| 认证增强 | 仅用户名密码 | AUTH 报文支持扩展认证(如 OAuth) |
实战价值:在千级设备以上的规模化部署中,5.0 的主题别名可减少 85% 主题带宽占用,共享订阅解决了单消费者瓶颈,细化原因码大幅降低运维排障成本。
六、主流实现与快速上手
6.1 常见 Broker
- EMQX:国产开源,高性能分布式,企业级功能丰富,国内应用最广
- Mosquitto:Eclipse 旗下,轻量经典,适合嵌入式和小型部署
- HiveMQ:企业级,Java 实现,集群能力强
- VerneMQ:Erlang 实现,高可用分布式
- 云厂商托管:AWS IoT Core、阿里云 IoT、腾讯云 IoT Explorer
6.2 常见客户端库
- Python:paho-mqtt
- Java/Android:Eclipse Paho Java
- JavaScript:MQTT.js(浏览器 / Node.js)
- C/C++:Eclipse Paho C、MQTT-C
- Go:paho.mqtt.golang
- 嵌入式:MQTT-C、lwMQTT
6.3 快速体验(Python 示例)
python
import paho.mqtt.client as mqtt
# 连接成功回调
def on_connect(client, userdata, flags, rc):
print(f"连接成功,返回码: {rc}")
client.subscribe("home/livingroom/temperature")
# 消息接收回调
def on_message(client, userdata, msg):
print(f"收到 [{msg.topic}]: {msg.payload.decode()}")
client = mqtt.Client(client_id="demo_client_001")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.emqx.io", 1883, 60)
# 发布一条消息
client.publish("home/livingroom/temperature", "25.5", qos=1)
client.loop_forever()
6.4 常见 Broker--EMQX
EMQX 是一个统一的 MQTT 平台,用于实时 AI 和 IoT 数据流传输。它可以连接、处理来自数百万台设备的数据,并将其传输到您的云端、AI 和分析平台。

EMQX 提供三种部署选项:完全托管的云(无服务器或专用服务器),可实现最快价值;自带云 (BYOC),可实现更好的隔离性和数据驻留;以及自主管理(企业版),可完全控制您自己的基础设施。所有选项均采用一致的 MQTT 核心架构。
七、典型应用场景
- 智能家居:设备状态上报、APP 远程控制、场景联动
- 工业物联网:产线传感器数据采集、设备远程运维、预测性维护
- 车联网:车辆位置上报、远程诊断、OTA 升级通知
- 智慧城市:路灯监控、环境监测、交通流量采集
- 智慧农业:土壤温湿度采集、灌溉自动控制
- 即时通讯:消息推送、在线状态同步
八、最佳实践建议
- 主题设计 :遵循层级语义,从大到小(如
产品/设备/功能),避免过深层级,预留扩展位 - QoS 选择:优先 QoS 0,关键数据用 QoS 1,非必要不用 QoS 2(开销是 QoS 1 的 2 倍)
- ClientID:确保全局唯一,建议使用设备 SN 或 UUID
- 安全加固:生产环境启用 TLS/SSL(8883 端口),配合用户名密码认证或证书认证
- 消息大小:单条消息建议控制在 256KB 以内,大数据分片传输
- 心跳设置:移动网络建议 30~60 秒,有线网络可设更长,兼顾电量与实时性