MQTT QoS 介绍

简介: MQTT QoS 介绍

QoS是用来干什么的?

QoS(Quality of Service) 是消息的发送方( Sender )和接受方( Receiver )之间达成的一个协议。用来保证消息稳定传输的机制,包括消息应答、存储和重传。


在这套机制下,提供了三种不同层次 QoS

QoS 级别 含义
QoS0 至多一次 Sender 发送的一条消息,Receiver 最多能收到一次,也就是说 Sender 尽力向 Receiver 发送消息,如果发送失败,也就算了
QoS1 至少一次 Sender 发送的一条消息,Receiver 至少能收到一次,也就是说 Sender 向 Receiver 发送消息,如果发送失败,会继续重试,直到 Receiver 收到消息为止,但是因为重传的原因,Receiver 有可能会收到重复的消息
QoS2 确保只有一次 Sender 发送的一条消息,Receiver 确保能收到而且只收到一次,也就是说 Sender 尽力向 Receiver 发送消息,如果发送失败,会继续重试,直到 Receiver 收到消息为止,同时保证 Receiver 不会因为消息重传而收到重复的消息


注意:QoSSenderReceiver 之间的协议,而不是 PublisherSubscriber 之间的协议。换句话说, Publisher 发布了一条 QoS1 的消息,只能保证 Broker至少收到一次这个消息;而对于 Subscriber 能否至少收到一次这个消息,还要取决于 SubscriberSubscribe 的时候和 Broker 协商的 QoS 等级。


QoS0

QoS0 等级下, SenderReceiver 之间一次消息的传递流程如下:

QoS0消息传递流程图.png

SenderReceiver 发送一个包含消息数据的 PUBLISH 包,然后不管结果如何,丢掉已发送的 PUBLISH 包,一条消息的发送完成。


QoS1

QoS1 要保证消息至少到达一次,所以有一个应答的机制。 SenderReceiver 的一次消息的传递流程如下:

QoS1消息传递流程图.png


流程:

  1. SenderReceiver发送一个带有数据的PUBLISH包,并在本地保存这个PUBLISH包。
  2. Receiver收到PUBLISH包以后,向Sender发送一个PUBACK数据包,PUBACK数据包没有消息体(Payload),在可变头中有一个包标识(Packet Identifier),和它收到的PUBLISH包中的Packet Identifier一致。
  3. Sender收到PUBACK之后,根据PUBACK包中的Packet Identifier找到本地保存的PUBLISH包,然后丢弃掉,一次消息的发送完成。


但是消息传递流程中可能会出现问题

  1. 如果Sender在一段时间内没有收到PUBLISH包对应的PUBACK,它将该PUBLISH包的DUP标识设为1(代表是重新发送PUBLISH包),然后重新发送该PUBLISH包。
  2. Receiver可能会重复收到消息,需自行去重。


QoS2

相比 QoS0QoS1 , QoS2 不仅要确保 Receiver 能收到 Sender 发送的消息,还需要确保消息不重复。它的重传和应答机制就要复杂一些,同时开销也是最大的QoS2 下,一次消息的传递流程如下所示:

QoS1消息传递流程图.png


流程:

  1. Sender发送QoS2PUBLISH数据包,数据包 Packet IdentifierP,并在本地保存该PUBLISH包;
  2. Receiver收到PUBLISH数据包后,在本地保存PUBLISH包的Packet Identifier P,并回复Sender一个PUBREC数据包,PUBREC数据包可变头中的Packet IdentifierP,没有消息体(Payload);
  3. Sender收到PUBREC,它就可以安全的丢弃掉初始Packet IdentifierPPUBLISH数据包。同时保存该PUBREC数据包,并回复Receiver一个PUBREL数据包,PUBREL数据包可变头中的Packet IdentifierP,没有消息体;
  4. Receiver收到PUBREL数据包,它可以丢掉保存的PUBLISH包的Packet Identifier P,并回复Sender一个可变头中 Packet IdentifierP,没有消息体(Payload)的PUBCOMP数据包;
  5. Sender收到PUBCOMP包,那么认为传输已完成,则丢掉对应的PUBREC数据包;


上面是一次完整无误的传输过程,然而传输过程中可能会出现以下情况:

  • 情况1:Sender发送PUBLISH数据包给Receiver的时候,发送失败;
  • 情况2:Sender已经成功发送PUBLISH数据包给Receiver了,但是Receiver发送PUBREC数据包失败;
  • 情况3:Sender已经成功收到了PUBREC数据包,但是PUBREL数据包发送失败;
  • 情况4:Receiver已经收到了PUBREL数据包,但是发送PUBCOMP数据包时发送失败


针对上述的问题,较为详细的处理方法 如下:

  • 不管是情况1还是情况2,因为Sender在一定时间内没有收到PUBREC,那么它会把PUBLISH包的DUP标识设为1,重新发送该PUBLISH数据包;
  • 不管是情况3还是情况4,因为Sender在一定时间内没有收到PUBCOMP包,那么它会重新发送PUBREL数据包;
  • 针对情况2Receiver可能会收到多个重复的PUBLISH包,更加完善的处理如下:

Receiver 在收到 PUBLISH 数据包之后,马上回复一个 PUBREC 数据包。并会在本地保存 PUBLISH 包的 Packet Identifier P ,不管之后因为重传多少次这个 Packet IdentifierP 的数据包, Receiver 都认为是重复的,丢弃。同时 Receiver 接收到 QoS2PUBLISH 数据包后,并不马上投递给上层,而是在本地做持久化,将消息保存起来(这里需要是持久化而不是保存在内存)。

  • 针对情况4,更加完善的处理如下:

Receiver 收到 PUBREL 数据包后,正式将消息递交给上层应用层,投递之后销毁 Packet Identifier P ,并发送 PUBCOMP 数据包,销毁之前的持久化消息。之后不管接收到多少个 PUBREL 数据包,因为没有 Packet Identifier P ,直接回复 PUBCOMP 数据包即可。


QoS降级

MQTT 协议中,从 BrokerSubscriber 这段消息传递的实际 QoS 等于: Publisher 发布消息时指定的 QoS 等级和 Subscriber 在订阅时与 Broker 协商的 QoS 等级,这两个 QoS等级中的最小那一个

Actual Subscribe QoS = MIN(Publish QoS, Subscribe QoS)


QoS和会话

如果 Client 想接收离线消息,必须使用持久化的会话( Clean Session = 0 )连接到 Broker ,这样 Broker 才会存储 Client 在离线期间没有确认接收的 QoS 大于 等于 1 的消息。

在发送 QoS12 的情况, Broker (此时为 Sender )会将发送的 PUBLISH 数据包保存到本地,直到收到一系列回复的数据包,然而 Client (此时为 Receiver )在离线期间无法回复相应的数据包,所以会一直存储。


QoS等级使用建议

QoS0 Client 和 Broker 之间的网络连接非常稳定,例如一个通过有线网络连接到 Broker 的测试用 Client
可以接受丢失部分消息,比如你有一个传感器以非常短的间隔发布状态数据,所以丢一些也可以接受
不需要离线消息
QoS1 需要接收所有的消息,而且应用可以接受并处理重复的消息
无法接受 QoS2 带来的额外开销,QoS1 发送消息的速度比 QoS2 快很多
QoS2 应用必须接收到所有的消息,而且应用在重复的消息下无法正常工作,同时也能接受 QoS2 带来的额外开销
相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
7月前
|
传感器 数据采集 物联网
MQTT 的 QoS 等级:QoS 0、QoS 1、QoS 2
MQTT 的 QoS 等级:QoS 0、QoS 1、QoS 2
496 0
EMQ
|
存储 传感器 缓存
MQTT QoS 0, 1, 2 介绍
MQTT协议中规定了消息服务质量QoS(Quality of Service),其核心是设计了多种消息交互机制来提供不同的服务质量,来满足用户在各种场景下对消息可靠性的要求。
EMQ
867 0
MQTT QoS 0, 1, 2 介绍
|
存储 网络协议 安全
最火的物联网技术MQTT,其服务质量QoS的三个级别分别是什么意思,本文一定对您有帮助!
MQTT是在 TCP/IP 之上使用的轻量级发布-订阅协议,常用于物联网的场景,MQTT 使用消息代理在发布消息的发送者和对这些消息感兴趣的接收者之间分派消息,同一个客户端可以发布和订阅消息。
412 0
最火的物联网技术MQTT,其服务质量QoS的三个级别分别是什么意思,本文一定对您有帮助!
EMQ
|
存储 消息中间件 传感器
MQTT QoS 设计:车联网平台消息传输质量保障
在本篇文章中,我们将借助 MQTT 协议的 QoS 特性,介绍车联网场景中的 MQTT 消息 QoS 设计,保障数据传输质量。
EMQ
327 0
MQTT QoS 设计:车联网平台消息传输质量保障
|
存储 网络性能优化
我的mqtt协议和emqttd开源项目个人理解(7) - Qos==2是如何保证消息只收到一次的
我的mqtt协议和emqttd开源项目个人理解(7) - Qos==2是如何保证消息只收到一次的
615 0
|
存储 Java 数据库连接
我的mqtt协议和emqttd开源项目个人理解(3) - 客户端publish消息QoS==0的源码分析
我的mqtt协议和emqttd开源项目个人理解(3) - 客户端publish消息QoS==0的源码分析
190 0
|
2月前
|
消息中间件 网络协议 JavaScript
MQTT常见问题之微消息队列mqtt支持ipv6失败如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
2月前
|
消息中间件 物联网 Java
MQTT常见问题之微消息队列配置失败如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
2月前
|
消息中间件 存储 监控
RabbitMQ:分布式系统中的高效消息队列
RabbitMQ:分布式系统中的高效消息队列
|
2月前
|
消息中间件 Java
springboot整合消息队列——RabbitMQ
springboot整合消息队列——RabbitMQ
76 0