Semghh

MQTT中 broker如何实现QoS

2024-12-24

我们都知道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解耦

image-20250213102222600

  • sender : 一次通信的消息发起者。
  • receiver : 一次通信的消息接收者。

2. Broker 如何达成QoS

Qos 有3个级别 0,1,2 他们的开销,依次提升但能提供更多的业务保证 :

Qos 0

Qos 0 :至多一次。

sender 发送 PUBLISH packet 并声明QoS为0。 broker接收到消息以后不做出任何回复。若此消息丢失,sender不知道并且sender 不会做任何重发。

因此,消息最多到达1次broker。

图示:

image-20250213102222600

Qos 1

Qos 1: 至少1次。

image-20250213102639040

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次。

image-20250213103024860

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


上一篇 定时器的实现

Comments

Content