一、简介
二、MQTT 的主要特性
三、开销小、带宽消耗少的原因
MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布/订阅消息传输协议,专为低带宽、不稳定网络环境设计。它的开销小、带宽需求低的原因有以下几点:
1. 头部结构简洁
- 固定头部:MQTT 的固定头部只有2字节,包括消息类型和标志位。对于一些简单的消息类型(例如 PINGREQ 或 DISCONNECT),固定头部就足够了,不需要额外的可变头部或负载。
- 可变头部和负载:仅在需要时才添加,不必要时省略。这减少了数据包的总大小。
2. 协议设计轻量化
- 简单的操作码:MQTT 的操作码和控制字段设计简单,减少了解析和处理的复杂度。
- 低开销的消息格式:消息格式紧凑,有效载荷不包含冗余信息。仅在需要时才传输必要的数据。
3. 发布/订阅模型
- 异步通信:发布/订阅模型允许设备在有数据时才发送消息,无需保持长时间的连接,减少了不必要的数据传输和带宽占用。
- 减少点对点连接:一个消息发布到主题,多个订阅者可以接收,避免了多个点对点连接,减少了网络流量。
4. 保持连接机制
- 心跳包(Keep Alive):通过心跳包机制保持连接,不频繁建立和断开连接,减少了 TCP 连接建立和断开的开销。
- PINGREQ 和 PINGRESP:用于保持连接的消息很小,仅有固定头部。
5. QOS(Quality of Service)等级
- QOS 0:最多一次传输,不需要确认,最小带宽消耗。
- QOS 1:至少一次传输,需要确认,带宽消耗适中。
- QOS 2:仅一次传输,最高保证,需要两阶段确认,带宽消耗相对较高。
- 按需选择:用户可以根据应用需求选择合适的 QOS 等级,优化带宽使用。
6. 保留消息和遗嘱消息
- 保留消息:服务器保留最新的消息,新的订阅者一连接就能收到,无需发送多个请求。
- 遗嘱消息:客户端异常断开时,服务器自动发布预设的遗嘱消息,无需额外的检测和重连开销。
7. 小型消息体
- 适用于小型消息:MQTT 适合小型消息传输,通常用于传感器数据、状态更新等小型数据包。
- 减少数据量:通过小型数据包传输,减少了整体数据量和带宽占用。
四、补充(心跳包)
心跳包(Keep Alive)机制是 MQTT 协议的一项重要特性,用于保持客户端和服务器之间的连接。以下是对这项机制的详细解释:
心跳包机制的工作原理
-
Keep Alive 时间间隔:
- 在 MQTT 连接建立时,客户端和服务器约定一个时间间隔,称为 Keep Alive 时间间隔(以秒为单位)。
- 在这个时间间隔内,如果客户端没有向服务器发送任何消息,则必须发送一个 PINGREQ(心跳请求)消息。
-
PINGREQ 和 PINGRESP:
- PINGREQ:客户端发送的心跳请求消息,通知服务器客户端仍然在线。
- PINGRESP:服务器收到 PINGREQ 后,发送回客户端的响应,确认连接正常。
作用
-
保持连接活跃:
- 即使客户端没有实际数据要发送,心跳包也可以确保连接不被服务器认为已断开。
- 这对于长时间空闲但需要保持连接的设备非常重要,例如 IoT 设备。
-
检测连接状态:
- 如果服务器在 Keep Alive 时间内未收到任何消息,包括 PINGREQ,则认为客户端已断开连接,可以采取相应的措施(例如发布遗嘱消息)。
- 同样,客户端如果在合理时间内未收到服务器的 PINGRESP,可以认为连接出现问题,尝试重连。
优势
-
减少频繁的连接建立和断开:
- TCP 连接的建立和断开是一个耗时且资源消耗较大的过程。
- 通过保持长时间的稳定连接,而不是频繁建立和断开连接,可以显著减少网络资源的开销。
-
高效的带宽利用:
- 心跳包非常小,通常只有固定的 2 字节头部,几乎不会占用带宽。
- 通过这种方式保持连接,比重新建立连接所消耗的带宽要少得多。
-
提高实时性:
- 保持连接的状态,使得客户端和服务器之间的通信可以在需要时立即进行,而不需要等待重新建立连接的时间。
示例
假设一个 IoT 设备需要每小时发送一次数据到服务器,而在其他时间段保持连接:
- 设备与服务器约定 Keep Alive 时间间隔为 60 秒。
- 每隔 60 秒设备发送一个 PINGREQ,服务器响应 PINGRESP。
- 设备在每小时的数据发送前不需要重新建立连接,可以立即发送数据。
通过这种方式,设备和服务器保持了一个稳定的连接,减少了频繁的连接建立和断开操作,降低了网络开销和资源消耗。
五、MQTT版本
MQTT 5.0 是在 MQTT 3.1.1 的基础上进行扩展和改进的版本,它添加了许多新的功能和特性,使协议更加完善和灵活。以下是对 MQTT 5.0 新增功能和改进的详细解释:
新增功能和改进
-
属性(Properties)
- 在 MQTT 5.0 中,每个 MQTT 控制报文(例如 CONNECT、PUBLISH、SUBSCRIBE 等)可以携带一组属性。这些属性提供了额外的元数据,可以用于控制消息的行为、传递额外的信息等。
- 例如,PUBLISH 报文可以包含消息过期间隔(Message Expiry Interval)、内容类型(Content Type)等属性。
-
改进的错误报告
- MQTT 5.0 引入了更多的返回码,使得错误报告更加具体和详细。
- 客户端和服务器可以在不同情况下返回不同的错误码,帮助诊断和处理错误。
-
共享订阅(Shared Subscriptions)
- 支持多个客户端共享一个订阅。这对于负载均衡非常有用,消息可以分发到多个订阅者中,而不是每个订阅者都接收到相同的消息。
-
会话过期间隔(Session Expiry Interval)
- 允许客户端在断开连接后指定会话的过期间隔。在指定的时间内,客户端可以重新连接并恢复之前的会话状态(如订阅和未传递的消息)。
-
消息过期间隔(Message Expiry Interval)
- 消息可以设置一个过期间隔。如果消息在这个时间内没有被传递,消息将被丢弃。这对于时间敏感的消息非常有用。
-
请求/响应模式(Request/Response Pattern)
- 支持直接在 MQTT 协议中实现请求/响应模式,客户端可以请求并等待响应,而不是单纯的发布和订阅。
-
用户属性(User Properties)
- 允许用户在消息中添加自定义属性。这些属性可以包含任何用户定义的键值对,提供了更大的灵活性。
-
流量控制(Flow Control)
- 引入了流量控制机制,通过设置最大消息量(Maximum Packet Size)和请求限速(Request Rate Limiting)来管理和控制消息的流量,防止网络拥塞和过载。
-
增强的订阅选项(Subscription Options)
- 订阅选项更加丰富,例如可以设置是否保留消息(Retain Handling)、指定的 QOS 等级等。
-
断开连接原因码(Disconnect Reason Codes)
- 当客户端或服务器断开连接时,可以提供具体的断开原因码,帮助诊断和处理连接问题。
举例说明
假设有一个 IoT 环境中的温度传感器网络,MQTT 5.0 的一些新特性可以提供以下优势:
-
属性(Properties):
- 在发布温度数据时,传感器可以在 PUBLISH 报文中包含内容类型(例如
application/json
)和消息过期间隔(例如 60 秒)。
- 在发布温度数据时,传感器可以在 PUBLISH 报文中包含内容类型(例如
-
改进的错误报告:
- 如果订阅失败,服务器可以返回详细的错误码,说明订阅失败的具体原因。
-
共享订阅:
- 多个监控系统客户端可以共享一个温度数据的订阅,服务器将消息负载均衡到各个监控客户端。
-
会话过期间隔:
- 当传感器设备临时掉线后重新连接,可以恢复之前的会话状态,而不需要重新订阅所有主题。
-
请求/响应模式:
- 监控系统可以请求某个传感器的数据,并在同一连接上接收到响应,而不是通过发布/订阅方式间接获取数据。
总结
MQTT 5.0 在 MQTT 3.1.1 的基础上增加了许多新功能和改进,使协议更加灵活、健壮和适应现代物联网应用的需求。这些改进包括属性机制、改进的错误报告、共享订阅、会话和消息的过期间隔、用户自定义属性、流量控制、增强的订阅选项以及具体的断开原因码等。通过这些特性,MQTT 5.0 提供了更强的可扩展性和可管理性,适用于更加复杂和多样化的应用场景。