我们都知道MQTT中消息的QoS级别,它和我们业务需求的可靠性息息相关。
那么对于Qos消息,broker做了什么来保证”精确一次”/”至少一次”/”至多1次”语义的呢?
1. MQTT
MQTT 是物联网最常见的协议之一。它运行在TCP之上,因此可以认为是应用层协议。
MQTT不关心 TCP层做的事情,它只定义了 消息是怎样在通信双方传递的。
物联网/弱网情况下,选择MQTT协议, 它的优势有:
- 协议头足够小,开销低
- 提供了3种Qos级别,可以在弱网条件下,适应多种业务需求
- 使用broker解耦通信双方,足够简单。
- 可以扩展到上千万的设备
- 安全,支持TLS
本文主要关心Qos和broker在Qos中都做了什么。
你需要理解的术语有:
- broker : MQTT的服务器,完成消息的接收、路由工作。
- client : 客户端。既是消息发送者,又可以是 消费者。 broker 和 client 是一组对立概念。
这张图能够帮你更好的理解 client 和 broker 。
broker 就是一组MQTT Server的实现。 message producer 把消息推给broker 与 message consumer解耦
- sender : 一次通信的消息发起者。
- receiver : 一次通信的消息接收者。
2. Broker 如何达成QoS
Qos 有3个级别 0,1,2
他们的开销,依次提升但能提供更多的业务保证 :
Qos 0
Qos 0 :至多一次。
sender 发送 PUBLISH packet 并声明QoS为0。 broker接收到消息以后不做出任何回复。若此消息丢失,sender不知道并且sender 不会做任何重发。
因此,消息最多到达1次broker。
图示:
Qos 1
Qos 1: 至少1次。
sender首先发送 PUBLISH QoS1 的数据包。 broker接收到packet以后,知道此次通信是QoS1,然后向 sender回复 PUBACK packet。
注意,此时broker不会缓存任何 packet数据包。不会做重复校验处理
若sender未在规定时间内收到 receiver的 PUBACK 数据包,那么它会尝试重新发送原始数据包,直到收到 PUBACK 为止。
broker在这个过程中不会缓存任何packet,因此收到一份数据包(可能是重传的)都会响应 PUBACK 。
所以 QoS 1 是消息至少1次(可能多次到达,消息可能重复)。
Qos 2
Qos 2: 精确1次。
Sender 向 Broker发送 QoS为2的 PUBLISH ,broker收到以后, broker会缓存packetID,并响应 PUBREC。
若sender 未收到PUBREC,则重传原始数据包。 broker收到重复 packetID的数据包丢弃,并响应PUBREC。
若sender正常收到PUBREC,则向broker发送 PUBREL , 只要 broker收到 PUBREL以后,就会释放所有保存的状态,并返回 PUBCOMP packet 。
在 broker收到 PUBREL 且 完全处理消息之前, broker都必须保存原始的packet。
若sender 收到 PUBCOMP packet 以后,则释放所有保存的状态, packetID 回收等待重新利用。
sender未收到 PUBCOMP ,则会重传 PUBREL。
broker必须保证响应每一次的 PUBREL,都回复 PUBCOMP
至此,QoS2结束。 QoS2保证了 Sender已经将原始packet传递到broker ,并且Sender已知 broker确实收到消息。
参考
https://www.hivemq.com/static/ebooks/hivemq-ebook-mqtt-essentials.pdf