MQTT 是什么?一文读懂 MQTT 协议的原理与优势

1,MQTT 是什么

MQTT(Message Queuing Telemetry Transport) 是一种轻量级的发布/订阅(Pub/Sub)消息协议!!它是协议,不是平台,就像 HTTP、TCP 一样,任何人都可以用它来自定义通信。最早由 IBM 提出,用于低功耗、低带宽场景下的数据传输,尤其适用于物联网(IoT)设备通信。

 

名称全称角色类比
MQTTMessage Queuing Telemetry Transport一种协议(通信规则)寄快递的规则,寄件人、寄给谁、格式等规定
MQTT实现者如:EMQX、Mosquitto、HiveMQ等MQTT协议的具体产品快递公司,比如顺丰、圆通、韵达等

类比参考:MQTT 与其实现者(如EMQX)的关系,就像 AMQP 与 RabbitMQ 的关系。

 

MQTT 核心概念如下:

角色说明
Broker(消息中转中心)MQTT服务器,负责转发消息
Publisher(发布者)比如无人机,定时上报状态(如定位、电量)
Subscriber(订阅者)比如后端系统,订阅无人机状态,接收消息
Topic(主题)消息分类路径,类似URL路径,如:drone/123/status


 

举个例子:温度传感器

  • 每一个设备是一个 MQTT 发布者(Producer),它定时上报温度数据;

  • 手机、电脑、服务器、Java等等,都可以是MQTT 的订阅者(Consumer)也就是客户端,订阅特定 topic,接收发来的信息;

  • 中间的通信由一个 MQTT 实现者(如 EMQX)负责中转和管理。

比如,图中 展示了 MQTT 的发布/订阅过程。温度传感器作为客户端连接到 MQTT Broker,并通过发布操作将温度数据发布到一个特定主题(例如 Temperature)。MQTT Broker 接收到该消息后会负责将其转发给订阅了相应主题(Temperature)的订阅者客户端。

(图片出自EMQX,侵删)

 

 

2,MQTT 的优势和应用场景

特性说明
低带宽、低功耗消息很小,适合物联网设备(比如蓝牙门锁、智能电表)
发布/订阅模型不需要设备互相知道 IP
支持 QoS 等级保证消息“至少一次”“至多一次”甚至“正好一次”
支持保留/遗嘱消息可以通知别人“我下线了”或者“我挂了”
支持断线重连网络差也能恢复连接

应用场景

应用场景说明
智能家居比如智能插座、温湿度传感器
汽车物联网车辆数据上传,远程监控
工业自动化远程设备状态监控
智能门锁控制开关门、上传日志等

 

 

3,MQTT 与 MQ 的关系与异同

MQTT和MQ是两个非常容易被混淆的概念。很多开发者容易把它和 RabbitMQ、Kafka 混为一谈。其实二者在定位、层次、使用场景上都存在显著差异。

MQTT 常用于 IoT 场景,而 MQ 通常是指实现了各种消息传输协议的中间件产品,如 RabbitMQ、RocketMQ 等。两者都基于生产者-消费者-Broker 架构,但 MQTT 是协议层,MQ 是产品层。

区别对比表

对比维度MQTTMQ
本质协议架构/中间件产品
设计目标轻量、低带宽、低功耗、实时解耦服务、异步处理、高吞吐
模式发布/订阅(Pub/Sub)多种:点对点、发布订阅、事务型等
使用者通常用于 物联网设备 通信通常用于 后端服务之间通信
常见产品EMQX、Mosquitto、HiveMQRabbitMQ、Kafka、RocketMQ、ActiveMQ
消息确认有 QoS(0, 1, 2)级别控制更强的持久化、事务等保障
协议层应用层协议(TCP/IP之上)实现通信机制的一种手段(不局限于协议)
适合场景智能家居、远程遥测电商下单、日志收集、订单系统异步解耦

比如现在有个智能门锁,它会在我开门的时候,记录下是指纹开门、人脸开门等。就是通过MQTT传递到后端,然后后端将这些动作记录到数据库,此时呢可以采用MQ进行异步处理。

 

他们最核心的差异:

- 消费模型不同(最本质差异)

MQ默认是竞争式的(就是一个消费者消费了,其它人就不用消费了。当然在一些MQ产品中比如RabbitMQ等,你也可以设成广播的)。

而MQTT 是“广播式”消费模型。它会通知这个topic上的所有订阅者。

实际上准确来说MQTT是"多播",也就是逐个分发给订阅者,并不是真正意义上的广播协议,它使用主题(Topic)做路由匹配,实现“组播效果”,但每个客户端的连接、QoS、ACK 都是单独维护的,因此它是“看起来像广播,实际上是点对点多路投递”。

 

- 订阅行为不同

MQTT 的订阅更灵活、轻量,无需提前声明结构。

  • MQTT 中,客户端只需订阅指定的 Topic 路径(如:device/lock/open) 即可,无需显式创建 Broker、Exchange、Queue。
  • MQ 则需要开发者显式声明:交换机、队列、绑定关系、路由规则,配置更复杂,但功能更强大。

 

- 消息存储机制不同

MQTT 默认不持久化消息,而 MQ 的消息则通常会被可靠地存储。

  • MQTT 的 Broker(如 EMQX)默认仅在 QoS=1/2 且 cleanSession=false 时才考虑持久化消息,每个 Topic 最多只会保留一条 Retain 消息(即“最后一条”),不会保存历史记录。
  • MQ(如 Kafka)则默认将消息持久化到磁盘,即便没有消费者在线,消息也不会丢失,支持延迟处理、离线分析等复杂场景。

MQTT 可以根据QoS的级别来配置"生产"消息这个行为一定被"生产"成功,但不保证有客户端在监听,MQTT Broker像一个喇叭,根据配置的QoS级别,它保证自己一定会"喊一下"这个喇叭。但不保证它喊的喇叭会被人听见,又或者有几个人听见。而MQ在这方面则完全不同,它在收到消息后是保证本地先存起来,防止消息丢失,再去处理后续的消息消费。

 

 

4,为什么物联网领域强烈推荐 MQTT 而不用HTTP

你必须要理解下面这几点。

在可能不稳定网络环境(家庭 Wi-Fi 信号边缘、蜂窝网络) 的物联网设备,MQTT 的设计优势是碾压性的。“专为物联网和资源受限环境设计”,意味着 MQTT 在 网络不好、设备性能差、电量有限、通信频繁但数据量小的环境下,表现比 HTTP 更加稳定、节能、实时、可靠

场景:一个低功耗蓝牙门锁,开锁上传一条记录。

维度HTTPMQTT说明
连接方式每次都要重新建立连接(TCP + TLS + 传头部)长连接(TCP 只建立一次)MQTT 建立连接后,可以一直保持(心跳维持)
数据体积较大(有大量 header)极小(只有必要数据)MQTT header 只占 2 字节起
实时性发了就断(非实时)实时推送,毫秒级适合做“开锁指令下发”
功耗连接 + 断开消耗高一直连接,省电特别重要!门锁是电池供电
网络要求网络波动时易失败支持断线重连、QoSMQTT 可以断线缓存、自动重发
传输方向客户端只能请求服务器服务端也可以主动下发指令HTTP 无法推送(除 WebSocket)
协议层应用层 HTTP应用层 MQTT(基于 TCP)MQTT 比 HTTP 更轻

HTTP 像是打一次电话就挂断,MQTT 像是一直保持在线的对讲机,适合设备随时上下线、随时传消息的环境。

 

 

作为IoT设备通信间的最佳协议之一,MQTT还提供了非常多实用的机制和功能。

 

5,掉线感知

MQTT 可以感知设备掉线,而且非常精准、轻量!有点类似于WebSocket 的连接断开而且比 WebSocket 更适合资源受限的设备场景,主要依赖两部分:心跳机制 + 遗嘱消息机制

 

5.1 心跳机制(Keep Alive)

工作原理:

  1. 客户端连接时会告诉 Broker 一个 Keep Alive 时间间隔(比如 60 秒)

  2. 这个间隔内,客户端必须发送任意一条 MQTT 报文(哪怕是 PINGREQ 心跳包);

  3. 如果 Broker 在 1.5 倍 Keep Alive 时间 内 没收到客户端任何消息,就认定这个客户端“掉线”;

  4. Broker 会主动断开连接。

心跳包说明:

  • MQTT 提供专门的心跳包叫 PINGREQ / PINGRESP

  • 一般是客户端发送 PINGREQ,Broker 回复 PINGRESP

 

5.2 遗嘱消息(Last Will and Testament)

工作原理:

  1. 客户端在连接时就设置好遗嘱消息(指定 topic、内容、QoS);

  2. 如果客户端正常断开连接(调用 DISCONNECT),不会触发遗嘱;

  3. 如果客户端意外掉线(如断电、断网,没发 DISCONNECT,心跳失联),

    • Broker 会在感知到客户端掉线后,自动向预设的 topic 发布这个遗嘱消息

    • 订阅了该 topic 的其他客户端就能收到通知,比如 “设备123离线了”。

 

5.3 模拟一下连接流程:

  1. 设备上线,连接 MQTT Broker 时可以设置一个“遗嘱消息”(Will Message):

    如果我哪天突然没了,请你替我 —— 发个 offline 消息到 lock/status/LOCK123456 这个 Topic。

  2. Broker 记住这份遗嘱了,设备继续正常通信

如果设备断电、断网、挂了

  1. Broker 开始等……等你发心跳(KeepAlive 时间 + 容忍时间)

  2. 超时没收到,Broker 确认:设备“失联了”

  3. 此时 Broker 代表设备,替你发出遗嘱消息(offline)!

 

 

6,送达确认机制(QoS 质量等级)

在实际业务中,我们经常需要确保“指令是否真正送达”。MQTT 协议为此设计了消息质量等级(QoS),它控制了消息在传输过程中的可靠性和重复性保障程度

6.1 MQTT 支持的三种 QoS 等级如下:

QoS 等级名称含义是否可能重复
0至多一次发了就不管了,不确认是否送达❗可能丢失
1至少一次确保 Broker 收到,可能重复投递✅可能重复
2仅一次完整的四次握手确保只投一次✅不会重复但性能最低

 

MQTT 的消息从“生产者发出”到“消费者收到”分为两段:

[生产者 → Broker] → [Broker → 订阅者]

生产者和订阅者都可以设置自己的 QoS,这两个方向相互独立控制,共同决定了消息最终送达订阅者的实际保障等级。

 

6.2 生产者 QoS:控制“是否送达 Broker”

  1. 生产者通过 client.publish(topic, qos) 设置发送的 QoS 等级;
  2. 控制的是:消息是否被 Broker 接收并确认(ACK)
  3. Broker 必须根据生产者的设置走对应的握手流程(如 QoS 1 的 PUBACK、QoS 2 的四步流程);
  4. 与订阅者是否存在、怎么订阅无关
  5. !!注意:QoS即使设置为1/2,也不代表它一定被人消费。它只能保证自己的消息到Broker了,有没有消费者、消费是否成功 则是一律不管的。

 

6.3 订阅者 QoS:控制“Broker 如何推送消息给我”

  1. 订阅者通过 client.subscribe(topic, qos) 声明自己“最多能接受什么等级的消息”;
  2. QoS 越高,意味着客户端需要处理更多的存储、去重、包序号等逻辑;
  3. Broker 不得超过订阅者请求的 QoS 等级进行推送.

订阅者 QoS = 1,意味着它希望 Broker 发来的消息最多是 QoS 1,即使原始消息是 QoS 2,也必须降级。也就是说 订阅者的QoS其实是一种预期,表示 “我可以接收最高什么级别的”。而当原始消息低于我们的预期时,将降级成原始消息的级别。反过来,我们预期低于原始消息,也会降级成我们预期的级别。

 

6.4 最终投递 QoS(Deliver QoS)

图示:

   ┌─────────────┐
   │          发布者             │
   │         QoS = 2            │
   └────┬────────┘
                │
               ▼
   ┌─────────────┐
   │           Broker            │
   └────┬────────┘
                │
    ┌────────────────┬──────────────┐
    ▼                                        ▼                                  ▼
订阅者:A (QoS2)             B(QoS1)                        C(QoS0)

 

最终QoS:
 A = min(2,2) = 2
 B = min(2,1) = 1
 C = min(2,0) = 0
 

反过来:

   ┌─────────────┐
   │          发布者             │
   │         QoS = 0            │
   └────┬────────┘
                │
               ▼
   ┌─────────────┐
   │           Broker            │
   └────┬────────┘
                │
    ┌───────────────┬──────────────┐
    ▼                                     ▼                                   ▼
订阅者A (QoS2)                  B(QoS1)                    C(QoS0)

 

最终QoS:
 A = min(0,2) = 0
 B = min(0,1) = 0 
 C = min(0,0) = 0

 

6.5 一个常见误区:是不是都设置 QoS = 2 就最安全?

你可能会想:干脆订阅者都设 QoS=2,是不是最保险?

技术上可以这么做,但并不推荐在生产中“统一拉满”,原因如下:

问题点说明
心理误区设置 QoS=2 会误导团队以为系统已足够可靠,反而忽略幂等、重试、日志等业务层保障
客户端资源消耗客户端 SDK 会预初始化 QoS 2 相关的结构,如包序号缓存、持久化机制,占用更多资源
性能下降QoS 2 要走四次握手,导致消息流转速度大幅降低,特别在弱网环境或 IoT 场景下更明显

 

这里有个问题:QoS2,需要四次握手,而HTTP还只需要3次。它是不是比HTTP还重,有没有必要用?

 

6.6 MQTT QoS2 的四次握手详细流程

MQTT 的 QoS2 确实比 HTTP 的三次握手“还重”,但它解决的是“消息投递这件事本身的幂等性”,而 HTTP 的三次握手解决的是“TCP 连接可靠性”,两者完全不一样。

举个例子:

设备发一条消息:"门锁已打开"

步骤如下:

客户端 → Broker
    PUBLISH(消息包,带 QoS2 标志)

Broker → 客户端
    PUBREC(我收到了,准备确认)

客户端 → Broker
    PUBREL(你确认我发的吧)

Broker → 客户端
    PUBCOMP(确认完成了,别再发了)

这就是所谓的 PUBLISH → PUBREC → PUBREL → PUBCOMP 四步。

 

6.7 常见场景下该选哪种 QoS?

场景推荐 QoS 等级是否能接受消息重复?是否能接受消息丢失?说明
🔓 设备上报“门已打开”QoS 1(至少一次)✅ 能接受(服务去重)❌ 不接受(不能丢记录)丢就没记录,重复最多多一条
📡 设备定时上报温度、电量等状态QoS 0(至多一次)✅ 能接受✅ 能接受实时性优先,偶尔丢一条无影响
📦 远程开锁指令(云端 → 设备)QoS 2(仅一次)❌ 不能接受❌ 不能接受重复=二次开锁,严重问题
📲 设备上线通知(状态变化)QoS 1✅ 能接受❌ 不接受若状态丢失,会认为设备掉线
🛠️ 配置/升级命令QoS 2❌ 不能接受❌ 不能接受丢了没配置,重复执行出错
🧪 数据采样(每秒10条)QoS 0✅ 能接受✅ 能接受高频无状态上报,重发浪费带宽
👨 用户操作反馈(按钮点击)QoS 1✅ 能接受❌ 不接受丢失可能影响用户体验
⚠️ 告警信息上传QoS 1 或 2(看严重级别)❌ 不接受❌ 不接受丢失报警 = 灾难

 

6.8 总结:

MQTT 的 QoS2 就是为了解决“消息只能送达一次”这个高要求场景而设计的,它通过四次握手实现消息发出的幂等性,性能较低但可靠性最高但绝大多数场景下,建议使用 QoS 1即可。因为即使是QoS2,在业务中依旧要做幂等处理(因为往往我们的消费者不会只有一个)。

 

 

7,断网期间消息缓存(Session + 离线队列)

为了应对“设备断网”这种常见场景,MQTT 还提供了“持久会话”和“离线消息缓存+补发”机制,只要你用对了配置,这些能力就自动为你工作,不需要手动管太多逻辑。

场景一:设备是发布者

比如:设备 ➜ 上报开锁事件 lock/event/open

// 1. 保持会话
options.setCleanSession(false);

// 2. 设置消息QoS
message.setQos(1);

这样配置的作用是:

如果设备临时断网(比如掉线3秒),MQTT SDK 会自动把这段时间要发的消息缓存起来,等网络恢复后补发出去,你无需自己管理“重发队列”。

场景二:设备是订阅者(用于接收服务端下发命令)

比如:平台 ➜ 给设备下发 “关锁指令” 到 lock/cmd/close

设备代码这样写:

options.setCleanSession(false); // 保持会话
client.subscribe("lock/cmd/close", 1); // 订阅指令主题,QoS=1

这时 cleanSession=false 的意义是:

如果设备断网,MQTT Broker 会保存这段时间发给它的消息(只要 QoS > 0),等设备一上线就自动推给它。

 

再对比 HTTP :

项目MQTT(带 QoS + 缓存)HTTP
断网时消息能否保存?✅ 会缓存❌ 失败直接丢
断网后能否补发?✅ 自动重发❌ 你要自己记住重新发
是否确认送达?✅ 有 ACK 和 QoS❌ 没有(除非你设计重试)

 

 

总结

MQTT 作为一种为物联网量身打造的轻量级通信协议,凭借其低带宽消耗、长连接机制、灵活的消息确认等级以及断线重连能力,已经成为智能设备通信的首选。相比传统的 HTTP 通信,它不仅更实时、省电,而且在弱网和高不确定环境中依然表现稳定。对于我们开发者而言,深入理解 MQTT 的核心机制(如 QoS、遗嘱消息、持久会话等)能够帮助我们构建出更可靠、更高效的 IoT 应用系统。未来随着物联网设备的普及,MQTT 的应用价值将愈发凸显,是每一位从业者必须掌握的重要技术。接下来我将会带来MQTT热门产品:EXMQ的部署和使用,敬请期待。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值