介绍
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是一种 轻量级、低带宽、低功耗 的发布/订阅(Pub/Sub)模式消息传输协议,专为物联网(IoT)、边缘设备、受限网络环境设计。由 IBM 于 1999 年开发,2014 年成为 OASIS 标准(OASIS MQTT v3.1.1),2019 年发布 v5.0 版本,进一步增强功能扩展性。
一、核心特性
MQTT 的设计核心是“适配资源受限场景”,关键特性如下:
轻量级:
- 协议头极简(固定头部仅 2 字节),消息开销小,适合带宽有限的网络(如 2G、NB-IoT、LoRa)。
- 客户端实现简单,占用设备资源少(内存、CPU),可运行在单片机(如 Arduino)、传感器等低端设备上。
发布/订阅模式:
- 解耦消息发送者(发布者,Publisher)和接收者(订阅者,Subscriber),两者无需直接通信,通过“主题(Topic)”关联。
- 支持 1 对多、多对多通信(一个主题可被多个订阅者订阅,一个发布者可向多个主题发送消息)。
服务质量(QoS)分级:
提供 3 级消息可靠性保障,按需选择(平衡可靠性与开销):- QoS 0(最多一次):“发后即忘”,消息可能丢失(如网络中断),开销最小(适合非关键数据,如传感器周期性上报)。
- QoS 1(至少一次):消息至少送达一次,可能重复(接收方需处理幂等性),通过“PUBACK 确认”机制实现(适合重要数据,如设备控制指令)。
- QoS 2(恰好一次):消息仅送达一次,无丢失、无重复,通过“PUBREC-PUBREL-PUBCOMP”三次握手实现(开销最大,适合核心数据,如金融交易、设备状态上报)。
会话保持与离线消息:
- 客户端与服务器建立连接时可指定“清除会话(Clean Session)”参数:
Clean Session = true:断开连接后,服务器删除客户端的订阅和未送达消息(临时会话)。Clean Session = false:断开连接后,服务器保留客户端的订阅和 QoS 1/2 未送达消息,客户端重连后可接收(适合设备离线后需补收消息的场景)。
- 客户端与服务器建立连接时可指定“清除会话(Clean Session)”参数:
遗嘱消息(Last Will and Testament, LWT):
- 客户端连接时可预设“遗嘱消息”和“遗嘱主题”,若异常断开连接(如设备断电、网络中断),服务器会自动向遗嘱主题发布该消息(用于设备离线告警,如“设备 X 离线”)。
保留消息(Retained Message):
- 发布者发送消息时可设置“保留标志(Retain)”,服务器会存储该主题的最新保留消息;新订阅者订阅该主题时,会立即收到服务器存储的保留消息(适合获取设备当前状态,如“查询设备 X 最新温度”)。
二、核心组件
MQTT 系统由 3 个核心角色组成,形成“发布-代理-订阅”架构:
发布者(Publisher):
- 消息的发送方,无需关心订阅者的存在,只需向指定“主题(Topic)”发送消息(可是设备、服务器、手机 App 等)。
- 示例:温度传感器向
sensor/temp/device1主题发布温度数据。
订阅者(Subscriber):
- 消息的接收方,需提前订阅感兴趣的“主题”,服务器会将该主题的消息推送给订阅者(可是设备、服务器、监控平台等)。
- 示例:监控平台订阅
sensor/temp/#主题,接收所有传感器的温度数据。
MQTT 服务器(Broker):
- 核心中间件,负责消息的路由、转发、存储(离线消息、保留消息),以及客户端连接管理、权限控制。
- 核心功能:接收发布者的消息 → 根据主题匹配订阅者 → 将消息推送给订阅者。
- 主流实现:Eclipse Mosquitto(开源轻量)、EMQ X(开源高性能,支持百万级连接)、AWS IoT Core(云服务)、Azure IoT Hub(云服务)、RabbitMQ(支持 MQTT 插件)。
三、关键概念
1. 主题(Topic)
- 消息的“地址标识”,用于发布者和订阅者的匹配,采用“层级结构”,用斜杠(
/)分隔层级(类似文件路径)。 - 示例:
sensor/temp/device1(设备 1 的温度传感器)、control/light/device2(设备 2 的灯光控制)。
主题通配符
订阅者订阅时可使用通配符匹配多个主题(发布者不可使用通配符):
+(单层通配符):匹配单个层级的任意字符串,示例:- 订阅
sensor/+/device1→ 匹配sensor/temp/device1、sensor/hum/device1(不匹配sensor/temp/room1/device1)。
- 订阅
#(多层通配符):匹配当前层级及以下所有层级的任意字符串,必须放在主题末尾,示例:- 订阅
sensor/#→ 匹配sensor/temp/device1、sensor/hum/device2/room1、sensor/light/device3。
- 订阅
2. 连接(Connection)
- 客户端与 Broker 通过 TCP/IP 建立连接(基础传输层,保证可靠性),也可通过 TLS/SSL 加密(MQTTs,端口 8883),防止消息被窃听或篡改(适合敏感数据传输)。
- 连接过程:客户端发送
CONNECT报文 → Broker 回复CONNACK报文(确认连接成功,返回连接状态码)。
3. 报文(Packet)
MQTT 协议通过标准化的“报文”实现通信,所有交互均基于报文(共 14 种报文类型),核心报文如下:
| 报文类型 | 作用 | 发送方 |
|---|---|---|
| CONNECT | 客户端向 Broker 发起连接 | 客户端 |
| CONNACK | Broker 确认连接(返回状态码) | Broker |
| PUBLISH | 发布者向 Broker 发送消息 | 发布者 |
| PUBACK | 确认 QoS 1 消息接收 | 订阅者/Broker |
| PUBREC/PUBREL/PUBCOMP | QoS 2 消息的三次握手确认 | 客户端/Broker |
| SUBSCRIBE | 订阅者向 Broker 订阅主题 | 订阅者 |
| SUBACK | Broker 确认订阅成功(返回 QoS 等级) | Broker |
| UNSUBSCRIBE | 订阅者取消订阅主题 | 订阅者 |
| UNSUBACK | Broker 确认取消订阅 | Broker |
| PINGREQ/PINGRESP | 心跳包(保持连接) | 客户端/Broker |
| DISCONNECT | 客户端主动断开连接 | 客户端 |
四、工作流程(示例)
以“温度传感器上报数据,监控平台接收数据”为例,完整流程如下:
连接建立:
- 温度传感器(发布者)向 MQTT Broker 发送
CONNECT报文,设置Clean Session = false、遗嘱消息(sensor/alert/device1→ “device1 离线”)。 - Broker 回复
CONNACK报文,确认连接成功。
- 温度传感器(发布者)向 MQTT Broker 发送
订阅主题:
- 监控平台(订阅者)向 Broker 发送
SUBSCRIBE报文,订阅主题sensor/temp/#(QoS 1)。 - Broker 回复
SUBACK报文,确认订阅成功,并返回实际 QoS 等级(1)。
- 监控平台(订阅者)向 Broker 发送
发布消息:
- 温度传感器向
sensor/temp/device1主题发布消息(内容:25.5℃,QoS 1,Retain = true)。 - Broker 接收消息后,向传感器回复
PUBACK确认(QoS 1 机制)。
- 温度传感器向
消息转发:
- Broker 匹配到
sensor/temp/device1属于sensor/temp/#订阅,向监控平台推送该消息(QoS 1)。 - 监控平台接收消息后,向 Broker 回复
PUBACK确认。
- Broker 匹配到
异常处理:
- 若传感器突然断电(异常断开连接),Broker 检测到连接中断,向
sensor/alert/device1主题发布遗嘱消息(“device1 离线”)。
- 若传感器突然断电(异常断开连接),Broker 检测到连接中断,向
重连与离线消息:
- 传感器恢复供电后,向 Broker 重连(
Clean Session = false),Broker 保留其订阅,若有未送达的消息(如断电期间的上报指令),会推送给传感器。
- 传感器恢复供电后,向 Broker 重连(
断开连接:
- 监控平台主动断开连接时,发送
DISCONNECT报文,Broker 关闭连接(若Clean Session = true,删除其订阅)。
- 监控平台主动断开连接时,发送
五、MQTT v3.1.1 与 v5.0 对比
v5.0 是 MQTT 的重大更新,解决了 v3.1.1 的功能局限,增强扩展性,核心新增特性:
| 特性 | v3.1.1 | v5.0 |
|---|---|---|
| 消息属性 | 无(仅通过标志位控制) | 支持自定义消息属性(如消息过期时间、主题别名) |
| 主题别名 | 不支持 | 可将长主题映射为短别名,减少消息开销 |
| 消息过期时间 | 不支持 | 发布消息时可设置 TTL,过期消息自动丢弃 |
| 共享订阅 | 不支持 | 多个订阅者共享一个主题的消息(负载均衡) |
| 响应主题 | 不支持 | 发布者可指定“响应主题”,订阅者可向该主题回复消息(请求-响应模式) |
| 连接认证 | 仅用户名/密码 | 支持扩展认证(如 OAuth2.0、JWT) |
| 错误码 | 仅 6 种连接错误码 | 新增 20+ 错误码,细化异常原因(如“主题不存在”“权限不足”) |
适用场景:
- v3.1.1:资源受限的低端设备(如单片机)、简单 IoT 场景(无需复杂功能)。
- v5.0:复杂 IoT 系统(如工业控制、智能城市)、需要请求-响应、负载均衡的场景。
六、典型应用场景
MQTT 因“轻量、可靠、低功耗”的特性,广泛应用于 IoT 及各类分布式场景:
物联网(IoT):
- 传感器数据上报(温度、湿度、气压等)。
- 设备远程控制(如灯光开关、空调调节、工业设备启停)。
- 智能家居(手机 App 控制家电,家电上报状态)。
- 智能穿戴(手环向手机上报心率、步数)。
工业互联网:
- 工业传感器(如机床振动、管道压力)向监控平台上报数据。
- 远程控制工业设备(如机器人、生产线),接收设备状态反馈。
车联网(V2X):
- 车辆向云端上报位置、速度、故障码。
- 云端向车辆推送导航信息、告警通知。
移动应用:
- 即时通讯(轻量化聊天,如设备告警通知)。
- 实时数据同步(如 App 与服务器的状态同步)。
边缘计算:
- 边缘设备(如网关)与云端的消息同步,减少云端压力。
七、主流实现与工具
1. MQTT Broker(服务器)
| 名称 | 特点 | 适用场景 |
|---|---|---|
| Eclipse Mosquitto | 开源、轻量、跨平台(Windows/Linux) | 开发测试、小型 IoT 系统 |
| EMQX | 开源、高性能(支持百万级连接)、支持 v5.0 | 大型 IoT 系统、工业互联网(6.0开始不支持windows) |
| VerneMQ | 使用 Erlang 开发的 MQTT 服务器 | 大型 IoT 系统、工业互联网(不支持windows) |
| AWS IoT Core | 云服务、托管式 Broker、支持 AWS 生态 | 云原生 IoT 应用 |
| Azure IoT Hub | 微软云服务、集成 Azure 其他服务 | 微软技术栈的 IoT 项目 |
| RabbitMQ | 多协议支持(MQTT/AMQP)、插件化 | 混合协议的分布式系统 |
2. MQTT 客户端(开发库)
- C/C++:Paho MQTT C(跨平台,适合嵌入式设备)、EMQ X C Client。
- Java:Paho MQTT Java(适合后端服务、Android 设备)、Eclipse Vert.x MQTT。
- C#:M2Mqtt(轻量)、Paho MQTT .NET(官方库)。
- Python:paho-mqtt(常用,适合脚本、边缘设备)。
- JavaScript:MQTT.js(适合前端、Node.js 服务)。
- 嵌入式:Paho MQTT Embedded C(适合单片机,如 STM32、Arduino)。
3. 调试工具
- MQTTX:开源跨平台客户端(支持 v3.1.1/v5.0,可视化主题订阅、消息发送,适合开发调试)。
- Mosquitto CLI:Mosquitto 自带的命令行工具(如
mosquitto_pub发布消息、mosquitto_sub订阅消息)。 - Postman:支持 MQTT 协议(v8.5+ 版本,适合 API 与 MQTT 协同调试)。
八、总结
MQTT 是 IoT 领域的“事实标准”协议,核心优势是轻量、可靠、低功耗,通过发布/订阅模式解耦设备与平台,支持灵活的 QoS 分级和离线消息机制,适配从低端传感器到云端服务器的全场景通信。
选择 MQTT 时需注意:
- 根据数据重要性选择 QoS 等级(平衡可靠性与开销)。
- 按需启用会话保持、遗嘱消息、保留消息(避免资源浪费)。
- 敏感场景使用 MQTTs(TLS 加密)和扩展认证(如 JWT)保障安全。
- 简单场景用 v3.1.1,复杂场景用 v5.0(支持共享订阅、请求-响应等高级功能)。