目录
1.1 QoS 0: 最多交付一次(At Most Once)
1.2 QoS 1: 至少交付一次(At Least Once)
1.3 QoS 2: 只交付一次(Exactly Once)
# 开篇
Qos设置:
很多时候,使用 MQTT 协议的设备都运行在网络受限的环境下,而只依靠底层的 TCP 传输协议,并不能完全保证消息的可靠到达。因此,MQTT 提供了 QoS 机制,其核心是设计了多种消息交互机制来提供不同的服务质量,来满足用户在各种场景下对消息可靠性的要求。
MQTT 定义了三个 QoS 等级,分别为:
- QoS 0,最多交付一次。
- QoS 1,至少交付一次。
- QoS 2,只交付一次。
其中,使用 QoS 0 可能丢失消息,使用 QoS 1 可以保证收到消息,但消息可能重复,使用 QoS 2 可以保证消息既不丢失也不重复。QoS 等级从低到高,不仅意味着消息可靠性的提升,也意味着传输复杂程度的提升。
在一个完整的从发布者到订阅者的消息投递流程中,QoS 等级是由发布者在 PUBLISH 报文中指定的,大部分情况下 Broker 向订阅者转发消息时都会维持原始的 QoS 不变。不过也有一些例外的情况,根据订阅者的订阅要求,消息的 QoS 等级可能会在转发的时候发生降级。
例如,订阅者在订阅时要求 Broker 可以向其转发的消息的最大 QoS 等级为 QoS 1,那么后续所有 QoS 2 消息都会降级至 QoS 1 转发给此订阅者,而所有 QoS 0 和 QoS 1 消息则会保持原始的 QoS 等级转发。
1. 精细MQS TT QoS的行为
让我们来进一步明确每种 MQS TT QoS 的行为,特别是消息传输过程中丢失与重复的风险和保障:
1.1 QoS 0: 最多交付一次(At Most Once)
- 特征:
- 无消息确认:发送者发送消息后,不需要确认消息是否到达接收者。
- 无重试:如果消息在传输过程中丢失,发送者不会再次发送该消息。
- 风险:消息可能丢失。在网络不稳定或发生传输错误时,消息可能不会到达接收者。
- 适用场景:适合对消息丢失不敏感的应用,例如发送传感器数据,实时监测数据,或日志记录。
1.2 QoS 1: 至少交付一次(At Least Once)
- 特征:
- 消息确认:发送者发送消息后,需要接收者(或代理)确认消息已接收(通过
PUBACK
)。 - 支持重试:如果发送者在规定时间内未收到确认,将重新发送消息,直到收到确认。
- 消息确认:发送者发送消息后,需要接收者(或代理)确认消息已接收(通过
- 风险:消息可能重复。由于重试机制,如果网络中断或接收确认消息丢失,发送者会重发,可能导致接收者收到重复的消息。
- 适用场景:适合需要确保消息到达但能处理重复消息的应用,例如状态更新、简单的事务操作。
1.3 QoS 2: 只交付一次(Exactly Once)
- 特征:
- 高级消息确认:通过复杂的四步握手过程(
PUBREC
、PUBREL
、PUBCOMP
),确保消息仅传输一次,避免重复。 - 支持重试:如果在任何一步未收到确认,发送者和接收者都会重试相应步骤,直到完成整个确认过程。
- 高级消息确认:通过复杂的四步握手过程(
- 风险:消息不会丢失或重复。确保了消息在传输中不会丢失,并且不会重复到达接收者。
- 适用场景:适合不能接受消息丢失或重复的应用,例如金融交易、订单处理等关键业务场景。
1.4 传输过程图示
QoS 级别 | 发送者行为 | 接收者行为 | 过程图示 |
---|---|---|---|
QoS 0 | 发送一次 | 立即处理 | Publisher -> Broker -> Subscriber |
QoS 1 | 发送->等待确认 | 确认->处理 | Publisher -> Broker <-> PUBACK -> Subscriber |
QoS 2 | 发送->等待 PUBREC -> PUBREL -> PUBCOMP |
确认 PUBREC -> 等待 PUBREL -> 确认 PUBCOMP |
Publisher -> Broker <-> PUBREC <-> PUBREL <-> PUBCOMP -> Subscriber |
1.5 总结
- QoS 0:适用于对消息丢失无所谓的场景。消息可能丢失。
- QoS 1:适用于需要保证消息到达但能接受重复消息的场景。消息可能重复。
- QoS 2:适用于需要严格保证消息不丢失且不重复的场景。消息不会丢失也不会重复。
选择合适的 QoS 级别取决于应用的可靠性需求和可以容忍的传输错误类型。
2. MQTT 数据大小限制和发送原理
2.1 EMQX 数据大小限制
- 默认最大数据大小:1 MB
- 最大可配置数据大小:256 MB
- 设置项:可以通过配置文件
emqx.conf
或 EMQX Dashboard 中的Max Packet Size
来调整。
2.2 Mosquitto 数据大小限制
- 默认最大数据大小:可以通过
mosquitto.conf
文件中的message_size_limit
配置项调整,具体默认值随版本和配置不同而异,一般设置为 268435455 字节 (约 256 MB) 。
2.3 发送数据的原理
MQTT 发送数据的基本流程:
- 连接:客户端与 MQTT Broker 建立连接。
- 订阅:客户端订阅一个或多个主题。
- 发布:客户端向订阅的主题发布消息。
- 接收:订阅该主题的客户端接收消息。
- 确认:根据 QoS(服务质量)等级,可能会有确认消息的发送。
详细步骤:
- 建立连接:客户端使用 MQTT 协议的 CONNECT 报文连接到 Broker。
- 订阅主题:客户端发送 SUBSCRIBE 报文,指定要订阅的主题。
- 发布消息:使用 PUBLISH 报文发布消息到某个主题。
- 消息转发:Broker 接收到消息后,将其转发给所有订阅该主题的客户端。
- 消息接收和确认:客户端接收消息,若 QoS 级别要求,需要发送 PUBACK(QoS 1)或 PUBREC/PUBREL/PUBCOMP(QoS 2)确认消息的递送。
2.4 MQTT 原理的时序图
MQTT(Message Queuing Telemetry Transport)协议是一种基于发布/订阅模式的轻量级消息传输协议,广泛应用于物联网(IoT)领域。以下是 MQTT 消息从客户端到 Broker 再到订阅者的完整时序图。
解释:
- CONNECT: 客户端发起连接请求。
- CONNACK: Broker 响应连接请求。
- SUBSCRIBE: 客户端订阅一个或多个主题。
- SUBACK: Broker 确认订阅。
- PUBLISH (QoS 0): 客户端发布消息,QoS 0 表示最多一次交付,不需要确认。
- PUBLISH (QoS 1): 客户端发布消息,QoS 1 表示至少一次交付,需要确认。
- PUBLISH (QoS 2): 客户端发布消息,QoS 2 表示精确一次交付,需经过四次握手确认。
- DISCONNECT: 客户端断开连接。
2.5 Qos中的四次握手
MQTT(Message Queuing Telemetry Transport)协议中的QoS(Quality of Service)级别有三个等级:0、1、2。QoS 2 是最高级别的保证消息传递的质量。
在MQTT中,QoS 2使用了四次握手来确保消息的可靠传递:
- 发起请求:发送端(Publisher)将消息发送给接收端(Subscriber),并请求QoS 2级别的确认。
- 接收确认:接收端收到消息后,向发送端发送确认收到的消息(PUBREC)。
- 发送确认:发送端接收到确认消息后,发送PUBREL给接收端,表示可以释放消息。
- 完成确认:接收端收到PUBREL后,发送最终的确认消息(PUBCOMP),表示消息已经完成传递。
这四次握手确保了消息的可靠性和顺序性,即使在网络不稳定或断开连接后,也能够确保消息不会丢失或重复传输。
2.6 相关配置示例
2.6.1 EMQX 配置 QoS 示例
在 emqx.conf
中:
mqtt.max_qos = 2
2.6.2 Mosquitto 配置 QoS 示例
Mosquitto 配置 QoS 示例
max_qos 2