Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MQTT中的QoS是什么???

MQTT中的QoS是什么???

作者头像
Hello工控
发布于 2025-05-15 05:12:34
发布于 2025-05-15 05:12:34
1270
举报
文章被收录于专栏:Hello工控Hello工控

我们上期介绍了MQTT的核心:

MQTT通信的核心:Topic主题

这期我们详细介绍下QoS,全称是Quality of Service (服务质量) 。(QoS) 是消息发送者和接收者之间的一个协议,定义了特定消息的交付保证级别。下面我们将更深入地探讨 MQTT 中不同的 Quality of Service (QoS) 级别。

QoS三种级别

消息的传输质量对于任何协议来说都非常重要。MQTT 已经定义了一套明确的服务质量标准。

MQTT 协议为物联网定义了三种消息传递质量(QoS)级别。每种 MQTT QoS 级别都伴随着数据传输速率的增加。然而,QoS 级别越高,确保 MQTT 消息传递的可能性就越高。MQTT 标准将 QoS 级别解耦于发布者和订阅者之间,使得客户端可以根据带宽和消息传递需求使用不同的 QoS 级别。客户端还可以为不同的 MQTT 主题在发布和订阅时使用不同的 QoS 级别。

  • QoS 0 — 最多传递一次且无消息传递保证
  • QoS 1 — 至少送达一次。可能会多次接收消息。然而,发布者或 MQTT 代理应该使用标志发送第二个消息作为重复消息。
  • QoS 2 — 保证只传递一次。

QoS 0 – At Most Once(最多一次)

入门级或第一级是 QoS 级别 0。也称为“一发即忘”。此级别确保消息只会被发送给接收方一次或根本不发送。不会有任何消息传递的保证;也就是说,接收方可能会或可能不会收到消息。订阅客户端或 MQTT 服务器不会对消息的接收发送任何确认。

QoS 0 可以在每个消息对于决策不是很重要的情况下使用。例如,学生的位置每 5 分钟不一定需要精确记录,即使我们可能使用这些数据来监控学生是否出席了课程。学生的具体位置不是关键信息。从宏观上看,学生在大学校园内的存在对于考勤系统来说是足够的。

QoS 1 – At Least Once(至少一次)

下一个 QoS 级别是 1。此级别确保消息至少会被接收方接收一次。消息可能会被接收方(订阅者或 MQTT 代理)多次接收,直到接收方发送 PUBACK 包给发送方(MQTT 代理或发布者)。包标识符用于发送方比较 PUBLISH 包和合适的 PUBACK 包。如果在一定时间内发送方没有收到 PUBACK 包,那么它会重新发送带有 Dup 标志的 MQTT 包,指示接收方如果已经接收到原始消息则忽略该包,并重新发送 PUBACK 包。

QoS 1 用于当每条消息在传输中都很重要,并且整个网络有足够的能力来处理额外负载并确保消息传输,即使在网络拥塞时通过重传也能保证消息送达。当根据速度和加速度等参数监控驾驶员行为时,收集的数据非常重要。因此,数据的传输需要设置为至少一次(QoS 1),以确保每条数据都可用于数据分析

QoS 2 –Exactly Once( 恰好一次)

第三级也是 MQTT QoS 的最高级别是 2,这被称为服务质量的最大级别。此级别确保接收方只会接收到每个消息一次。这是最安全的服务质量级别,因为在发送方和接收方之间至少有两个响应流可以提供消息保证。

为了实现这一点,QoS 2 涉及发送方和接收方之间的四步握手。消息的传递将由发送方和接收方使用原生 PUBLISH 消息的包标识符来组织。

发送方将 QoS 2 PUBLISH 包发送给接收方。然后,接收方适当地处理发布消息,并通过发送 PUBREC 包给发布方来确认 PUBLISH 包。如果发布方未收到 PUBREC,它将带有 DUP 标志重新发送该包,直到收到确认为止。

发布者在接收到 PUBREC 数据包后会存储该数据包,并回复 PUBREL 数据包。此时,原始的发布消息已不再需要存储在发送方的数据库中,可以安全地丢弃。包标识符用于将 PUBLISH 数据包与合适的 PUBREC 和 PUBREL 数据包配对。

接收者在接收到 PUBREL 后,会使用相同的包标识符向发送者回复 PUBCOMP 数据包。接收者可以在发送 PUBCOMP 的同时完成数据处理。当整个 QoS 2 流程完成后,发送者将获得投递确认。

如果数据包在传输途中丢失,发送方需要在合理的时间内重新发送消息。无论发送方是 MQTT 客户端还是 MQTT 代理,这一点都同样适用。接收方有责任对每个命令消息做出相应的响应。

对于关键任务功能,如果交付时间非常重要,应使用 QoS 2。对于患者监测系统,数据与时间的关系对于所有关键指标(如心率、呼吸、血氧饱和度等)都非常重要,建议使用最高 MQTT QoS 级别以确保及时的数据交付。

MQTT QoS 级别差异是如何处理的?

消息的质量服务是在两个连接到服务器或代理的客户端之间分配的,而不是端到端的。因此,客户端(订阅者)接收到的消息的质量服务级别取决于发布的消息的质量服务级别和订阅主题的质量服务级别。简而言之,接收到的消息最终的质量服务取决于发布和订阅的客户端的质量服务。

连接到代理后,订阅客户端将使用带有 QoS 属性的消息告知代理,它需要的消息的 QoS 属性。

以下表格提供了数据将在订阅的 MQTT 客户端端以哪种 QoS 级别接收的详细方案:

因此,发送方和接收方定义的 QoS 级别可以不同,最终接收到的消息的 Qos 取决于发布和订阅的消息的 Qos共同结果。

图片
图片

如何在MQTT中选择不同的QoS?

确定数据是信号还是噪声有助于决定使用哪个 Qos 级别。在医疗保健、核能、国防等关键行业中进行数据发布和收集时,每条数据都很重要,因此每条消息都必须使用 Qos 2。如果客户端能够处理重复消息,可以使用 Qos 1 代替 Qos 2。

下面详细介绍如何来选择合适的QoS?

适合使用QoS 0的情况:

  • 与接收方之间有完全或大部分稳定的连接。QoS 0 的经典用例是通过有线连接将测试客户端或前端应用程序连接到 MQTT 代理。
  • 不介意偶尔有几条消息丢失。如果数据不很重要,或者数据发送间隔很短,允许一些消息丢失是可以接受的。
  • 不需要消息队列。只有当断开连接的客户端的 QoS 为 1 或 2 且具有持久会话时,消息才会被排队。

适合使用QoS 1的情况:

  • 需要接收每条消息,并且你的应用场景能够处理重复消息。QoS 级别 1 是最常用的级别,因为它保证消息至少送达一次,但允许多次送达。当然,你的应用程序必须能够容忍重复消息并相应地处理它们。
  • 承受不了 QoS 2 的开销。QoS 1 比 QoS 2 更快地传递消息。

适合使用QoS 2的情况:

  • 对您的应用程序来说,接收所有消息且仅一次至关重要。这通常发生在重复投递会对应用程序用户或订阅客户端造成危害的情况下。请注意开销,并且知道 QoS 2 交互需要更多时间来完成。

MQTT 中 QoS 的常见问题

Q: 如何为 MQTT 中的具体消息或主题分配不同的 QoS 等级?

A: 你可以将消息的 QoS 等级分配在 PUBLISH 包中。

Q:为什么 QoS 0 消息会丢失?

A: QoS 消息会丢失,因为在此级别没有确认机制。如果由于网络问题导致消息在传输过程中丢失,或者在消息发送时订阅者离线,该消息将丢失。发布者无法知道消息是否成功接收,并不会尝试重新发送。

Q:如果多个客户端以不同的 QoS 级别订阅同一个主题会发生什么?

A: 如果多个客户端订阅了同一个主题,但具有不同的质量 of 服务(QoS)级别,代理会根据每个客户端订阅的 QoS 级别向其发送消息,而不是消息被发布时的 QoS 级别。

Q:如果保留消息的 QoS 级别与订阅者的订阅不同会发生什么?

A: 代理将在消息发布时设置的 QoS 级别与订阅的 QoS 级别较低的那个级别上投递保留消息。

Q:如果发送的 QoS 0 消息没有被订阅者接收,会发生什么?

A: 如果使用质量等级(QoS)0 发送的消息没有被订阅者接收,消息将会丢失。

Q: QoS 2 在 MQTT 中使用了哪些额外机制来保证消息传递?

A: 为了提供这一保证,QoS 2 在发布者和接收者(可能是代理或客户端,取决于消息的方向)之间引入了一个四步握手过程。这个过程涉及使用 PUBLISH、PUBREC、PUBREL 和 PUBCOMP 消息。

Q: 为什么 QoS 1 消息会被复制?如何处理消息的重复和重新排序?

A: 如果代理收到了原始消息并发送了 PUBACK,但 PUBACK 没有到达发布者(再次,可能是由于网络问题),那么代理将收到重复消息。在发布消息时,在负载中包含一个唯一的标识符或序列号。

Q: 使用 QoS 2 在消息开销和交付延迟方面有哪些权衡?

A: 消息开销 - 相比 QoS 0 或 1,额外的通信结果产生了更多的网络流量并使用了更多的带宽。传输延迟 - 由于四步握手所需的额外往返次数,QoS 2 比 QoS 0 或 1 的端到端延迟更高。

Q: 使用更高的 QoS 级别是否会影响带宽或网络利用率?

A: 是的,在 MQTT 中使用更高的 Quality of Service (QoS) 级别确实会影响带宽和网络利用率。

Q: 不同 QoS 级别的情况下,MQTT 是如何处理发布者和订阅者之间的交互的?

A: 当发布者向代理发送消息时,会指定消息的 QoS 级别。代理会根据发布者指定的 QoS 级别来确认和处理该消息。当代理向订阅者发送消息时,消息的 QoS 级别是发布者发布的 QoS 级别和订阅者订阅主题的 QoS 级别中的较低者。

Q: 当网络连接中断时,QoS 1 或 QoS 2 的消息会发生什么?

A: 在 MQTT 中,当网络连接中断时,QoS 1 和 QoS 2 消息的处理取决于连接中断时消息传递过程的阶段,以及是否使用了持久会话(也称为清洁会话clean sessions)。

Q: 使用不同 QoS 级别时,MQTT 是如何处理反向压力(backpressure)的?

A: MQTT 本身没有内置处理反向压力的机制,但该概念在与质量服务(QoS)级别相关时是相关的,并且可以进行管理。

Q: 我可以为较高 QoS 级别的消息配置重传尝试的次数吗?

A: 虽然 MQTT 协议没有明确定义重传的限制,但你使用的客户端库或代理可能会允许你配置这一点。具体细节取决于你使用的具体实现.

参考链接:

  1. https://www.bevywise.com/blog/mqtt-qos-level-use/
  2. https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels/
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Hello工控 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档