gOdm@'s BLOG

MQTT协议知识整合

版权信息

warning

本文章为博主原创文章。遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。


本篇参考 EMQ的官方教学文档——MQTT 教程 2026:从入门到精通 | EMQ

1. MQTT概述

1.1. 什么是MQTT?

MQTT(Message Queuing Telemetry Transport)是一种轻量级、基于发布-订阅模式的消息传输协议,适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。它在物联网应用中广受欢迎,能够实现传感器、执行器和其它设备之间的高效通信。

1.2. MQTT的部分特点

2. MQTT的工作原理

MQTT 是基于发布-订阅模式的通信协议,由 MQTT 客户端通过主题(Topic)发布或订阅消息,通过 MQTT Broker 集中管理消息路由,并依据预设的服务质量等级(QoS)确保端到端消息传递可靠性。

2.1. MQTT客户端

任何运行MQTT 客户端库的应用或设备都是 MQTT 客户端。

2.2. MQTT Server/Broker

MQTT Server 是负责处理客户端请求的关键组件,包括建立连接、断开连接、订阅和取消订阅等操作,同时还负责消息的转发

2.3. 发布-订阅模式

不同于客户端-服务器模式,它将发送消息的客户端(发布者)和接收消息的客户端(订阅者)进行了解耦。发布者和订阅者之间没有直接连接,而是通过 MQTT Server 来负责消息的路由和分发。

2.4. 主题(Topic)

MQTT 协议根据主题来转发消息。

2.5. QoS

MQTT 提供了三种服务质量(QoS),在不同网络环境下保证消息的可靠性。

3. MQTT的工作流程

  1. 客户端使用 TCP/IP 协议与 Broker 建立连接,可以选择使用 TLS/SSL 加密来实现安全通信。客户端提供认证信息,并指定会话类型(Clean Session 或 Persistent Session)。

  2. 客户端既可以向特定主题发布消息,也可以订阅主题以接收消息。当客户端发布消息时,它会将消息发送给 MQTT Broker;而当客户端订阅消息时,它会接收来自Broker转发的与订阅主题相关的消息。

  3. MQTT Broker 接收发布的消息,并将这些消息转发给订阅了对应主题的客户端。它根据 QoS 等级确保消息可靠传递,并根据会话类型为断开连接的客户端存储消息。

4. MQTT的特性

4.1. 主题(topic)与通配符

更多内容请参见——MQTT 主题与通配符(Topics & Wildcards)入门手册 | EMQ

4.1.1. 主题

MQTT 主题本质上是一个 UTF-8 编码的字符串,是 MQTT 协议进行消息路由的基础。MQTT 主题类似 URL 路径,使用斜杠 / 进行分层:

chat/room/1
sensor/10/temperature
sensor/+/temperature
sensor/#

4.1.2. 特殊主题

  1. 以 $SYS/ 开头的主题为系统主题。系统主题主要用于获取MQTT 服务器自身运行状态、消息统计、客户端上下线事件等数据。目前,MQTT 协议暂未明确规定 $SYS/ 主题标准,但大多数 MQTT 服务器都遵循该标准建议

  2. 以 $share 开头的共享订阅主题。这是MQTT5.0引入的新特性,请参见——

4.1.3. 通配符

MQTT 主题通配符包含单层通配符 + 及多层通配符 #,主要用于客户端一次订阅多个主题。

4.2. QoS

更多内容请参见——MQTT QoS 0、1、2 解析:快速入门指南 | EMQ

引入QoS解决在不同场景下对可靠消息传递的要求。比如有些不需要那么严格但要求效率,有些则需保证数据的可靠性。

MQTT 中的 QoS 指的是发布者与订阅者之间消息传递的保证级别。它提供三个服务级别:

使用 QoS 0 可能丢失消息,使用 QoS 1 可以保证收到消息,但消息可能重复,使用 QoS 2 可以保证消息既不丢失也不重复。QoS 等级从低到高,不仅意味着消息可靠性的提升,也意味着传输复杂程度的提升。

大部分情况下 Broker 向订阅者转发消息时都会维持原始的 QoS 不变。不过也有一些例外的情况,根据订阅者的订阅要求,消息的 QoS 等级可能会在转发的时候发生降级。

例如,订阅者在订阅时要求 Broker 可以向其转发的消息的最大 QoS 等级为 QoS 1,那么后续所有 QoS 2 消息都会降级至 QoS 1 转发给此订阅者,而所有 QoS 0 和 QoS 1 消息则会保持原始的 QoS 等级转发。

4.2.1. QoS 0 - 最多传一次

QoS 0 消息即发即弃,不需要等待确认,不需要存储和重传。类比UDP。所以在网络不稳定的情况下会出现丢包的问题。

4.2.2. QoS 1 - 至少传一次

QoS 1 加入了应答与重传机制,发送方只有在收到接收方的 PUBACK 报文以后,才能认为消息投递成功,在此之前,发送方需要存储该 PUBLISH 报文(发布报文)以便下次重传。

重传时报文中的 DUP 标志会被设置为 1,已表示这是一个重传的报文。但是接收方并不能因此判断曾经是否接收过这个消息。比如下面两种情况:

  1. 接收方收到了报文,但发送方由于没有收到 PUBACK 报文而重传了 PUBLISH 报文。
  2. 接收方没有接收到报文。

由于我们无法区分这两种情况,所以只能让接收方将这些 PUBLISH 报文都当作全新的消息来处理。因此当我们使用 QoS 1 时,消息的重复在协议层面上是无法避免的。

如何为QoS1去重?一个比较常用且简单的方法是,在每个 PUBLISH 报文的 Payload(实际的数据内容) 中都带上一个时间戳或者一个单调递增的计数,这样上层业务就可以根据当前收到消息中的时间戳或计数是否大于自己上一次接收的消息中的时间戳或计数来判断这是否是一个新消息。

4.2.3. QoS 2 - 只传一次

QoS 2 解决了 QoS 0、1 消息可能丢失或者重复的问题,但相应地,它也带来了最复杂的交互流程和最高的开销。 每一次的 QoS 2 消息投递,都要求发送方与接收方进行至少两次请求/响应流程。

具体流程可参见前面的链接。这里篇幅原因不详说 其实是自己也没明白

4.3. 保留消息(Retained)

更多内容请参见——MQTT 保留消息是什么?如何使用? | EMQ

4.3.1. 什么是?

发布者发布消息时,如果 Retained 标记被设置为 true,则该消息即是 MQTT 中的保留消息(Retained Message)。MQTT 服务器会为每个主题存储最新一条保留消息,以方便消息发布后才上线的客户端在订阅主题时仍可以接收到该消息。

4.3.2. 何时用?

发布-订阅模式,订阅者无法主动向发布者请求消息。订阅者何时收到消息完全依赖于发布者何时发布消息,这在某些场景中就产生了不便。

借助保留消息,新的订阅者能够立即获取最近的状态,而不需要等待无法预期的时间,例如:

需要注意的是,在保留消息发布前订阅主题,将不会收到保留消息。需要待保留消息发布后,重新订阅该主题,才会收到保留消息。 可通过消息中的保留标志位判断是否是保留消息。

4.3.3. 保留多久?怎么删?

保留消息虽然存储在服务端中,但它并不属于会话的一部分。因此即使会话已经结束,保留消息也不一定被删除。删除保留消息有以下几种方式:

4.3.4. MQTT 5.0 对保留消息的改进

MQTT 5.0 新增了消息过期间隔属性,发布时可使用该属性设置消息的过期时间,不管消息是否为保留消息,都将会在过期时间后自动被删除。具体介绍请参见本节头部链接。

4.4. 遗嘱消息(Will)

更多内容请参见——遗嘱消息(Will Message)介绍与示例 | MQTT 5.0 特性详解 | EMQ

4.4.1. 什么是?

在 MQTT 中,客户端可以在连接时在服务端中注册一个遗嘱消息,与普通消息类似,我们可以设置遗嘱消息的主题、有效载荷等等。当该客户端意外断开连接,服务端就会向其他订阅了相应主题的客户端发送此遗嘱消息。这些接收者也因此可以及时地采取行动,例如向用户发送通知、切换备用设备等等。

借助遗嘱消息,订阅者可以感知到发布者是否保持活跃,根据不同情况做出不同反应。

客户端正常下线的情况是发送一个 Reason Code 为 0x00 的 DISCONNECT 报文然后关闭网络连接,服务端不会发布遗嘱消息。只要连接在服务端没有收到 Reason Code 为 0x00 的 DISCONNECT 报文的情况下关闭,那么服务端都需要发送遗嘱消息。

遗嘱消息总是在客户端“死亡”后被发布,在某种意义上,它也是客户端发出的最后一个消息。

4.4.2. 使用技巧

4.4.3. MQTT 5.0 对遗嘱消息的改进

很多时候,网络连接的中断是短暂的,所以客户端往往能够重新连接并继续之前的会话。这导致遗嘱消息可能被频繁地且无意义地发送。

所以 MQTT 5.0 专门为遗嘱消息增加了一个 Will Delay Interval 属性,这个属性决定了服务端将在网络连接关闭后延迟多久发布遗嘱消息,并以秒为单位。

具体介绍请参见本节头部链接。

4.5. 持久会话与Clean Session

更多内容请参见——MQTT 持久会话与 Clean Session 详解 | EMQ

4.5.1. 持久会话

MQTT 客户端与服务器的连接可能随时会因为网络波动及资源限制而异常断开。为了解决网络连接断开对通信造成的影响,MQTT 协议提供了持久会话功能。

MQTT 客户端在发起到服务器的连接时,可以设置是否创建一个持久会话。持久会话会保存一些重要的数据,以使会话能在多个网络连接中继续。持久会话主要有以下三个作用:

4.5.2. 持久会话能存储的数据

客户端中存储的会话数据

服务端中存储的会话数据

4.5.3. 使用Clean Session开启持久会话

Clean Session 是用来控制会话状态生命周期的标志位,为 true 时表示创建一个新的会话,在客户端断开连接时,会话将自动销毁。为 false 时表示创建一个持久会话,在客户端断开连接后会话仍然保持,直到会话超时注销。

注意: 持久会话能被恢复的前提是客户端使用固定的 Client ID 再次连接,如果 Client ID 是动态的,那么连接成功后将会创建一个新的持久会话。

4.5.4. 会话会保留多久?

MQTT 3.1.1 没有规定持久会话应该在什么时候过期,如果仅从协议层面理解的话,这个持久会话应该永久存在。但在实际场景中这并不现实,因为它会非常占用服务端的资源,所以服务端通常不会完全遵循协议来实现,而是向用户提供一个全局配置来限制会话的过期时间。

当客户端确定不再需要会话时,可使用 Clean Session 为 true 进行重连,重连成功后再断开连接。如果是 MQTT 5.0 则可在断开连接时直接设置 Session Expiry Interval 为 0,表示连接断开后会话即失效。(见后文)

4.5.5. MQTT 5.0 对会话的改进

MQTT 5.0 提供了 Clean Start 和 Session Expiry Interval 这两个连接字段来控制会话的生命周期。以避免永久保留持久会话。

5. MQTT 5.0 的新特性

5.1. 请求/响应(Request/Response)

可以实现订阅端对发布端的响应(类似函数的return)。解决了发布端无法知道对端执行结果/是否收到包的问题

请参见——请求 / 响应 (Request / Response) 介绍与示例 | MQTT 5.0 特性详解 | EMQ

5.2. 用户属性(User Properties)

一种自定义属性,允许用户向 MQTT 消息添加自己的元数据,传输额外的自定义信息以扩充更多应用场景。让用户可以扩展标准协议。

请参见——用户属性 - MQTT 5.0 新特性 | EMQ

5.3. 主题别名(Topic alias)

将主题长度较长且常用的主题名缩减为一个双字节整数来降低发布消息时的带宽消耗。

请参见——主题别名 - MQTT 5.0 新特性 | EMQ

5.4. Payload Format Indicator 和 Content Type

Payload Format Indicator用于指定报文有效载荷的格式。如果 Payload Format Indicator 的值为 0 或者没有指定这个属性,表示当前有效载荷是未指定的字节流;而如果这个属性的值为 1,则表示当前有效载荷是 UTF-8 编码的字符数据。

Content Type 的值是一个 UTF-8 编码的字符串,用来描述应用消息的内容,这可以帮助接收端了解如何解析应用消息的有效载荷。例如,消息的内容是一个 JSON 对象,那么 Content Type 可以被设置为 “json”。这个字符串的具体内容完全由发送端和接收端决定,服务端不会验证这个属性,只负责将这个属性原封不动地转发给订阅者。

请参见——Payload Format Indicator 和 Content Type 介绍与示例 | MQTT 5.0 特性详解 | EMQ

5.5. 共享订阅(Shared Sub)

当多个客户端共享一个订阅时,服务端会把消息一个一个送给订阅者,而不是一次性同时送给订阅者。就像串行和并发的区别。

请参见——共享订阅介绍与示例 | MQTT 5.0 特性详解 | EMQ


5.6. 更多

不想写了。。。

请参见——MQTT 教程 2026:从入门到精通 | EMQ


共计约5.4k字。于2026/04/21首次发布,最后更新于2026/04/28。

本文章为博主原创文章。遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

  1. 1. MQTT概述
    1. 1.1. 什么是MQTT?
    2. 1.2. MQTT的部分特点
  2. 2. MQTT的工作原理
    1. 2.1. MQTT客户端
    2. 2.2. MQTT Server/Broker
    3. 2.3. 发布-订阅模式
    4. 2.4. 主题(Topic)
    5. 2.5. QoS
  3. 3. MQTT的工作流程
  4. 4. MQTT的特性
    1. 4.1. 主题(topic)与通配符
    2. 4.2. QoS
    3. 4.3. 保留消息(Retained)
    4. 4.4. 遗嘱消息(Will)
    5. 4.5. 持久会话与Clean Session
  5. 5. MQTT 5.0 的新特性
    1. 5.1. 请求/响应(Request/Response)
    2. 5.2. 用户属性(User Properties)
    3. 5.3. 主题别名(Topic alias)
    4. 5.4. Payload Format Indicator 和 Content Type
    5. 5.5. 共享订阅(Shared Sub)
    6. 5.6. 更多