理解MQTT订阅者QoS

23

我刚接触MQTT,并了解了在发布消息时决定的QOS级别的含义:

  • 0 当我们更愿意让消息根本不到达而不是到达两次时
  • 1 当我们希望消息至少到达一次,但不在乎它是否到达两次(或更多)
  • 2 当我们希望消息到达一次。
  • 较高的QOS值意味着传输速度较慢

我注意到订阅者端也可以设置他们将接收的“最大QOS级别”。引用自这里

例如,如果使用QoS 2发布消息并且客户端使用QoS 0进行订阅,则将使用QoS 0向该客户端传递消息。

这是否意味着消息可能不会到达客户端(QOS 0),尽管发布者以QOS 2发送了它?

对于缺乏经验的开发人员来说,这可能是一个重要问题-例如,在npm mqtt package中,subscribe函数的默认QOS为0! (在我看来,默认值应该是最大值2,即“让发布者决定QOS”)。

4个回答

18

您是正确的,QoS 2级别发布的消息无法保证会到达使用QoS 0级别的订阅者手中。如果对于该订阅者接收消息很重要,他们应该使用QoS 1或2级别。这是针对任何特定应用程序需要决定的事情。

我建议将您对QoS 0级别的定义重写为“至多一次”,即消息将被接收或不会被接收,不会出现重复的情况。

关于默认QoS - 我认为大多数客户端将QoS 0级别设置为默认值。我认为将QoS 1或2级别作为默认值设置并不会帮助没有经验的开发人员,他们仍然需要理解自己在做什么以及考虑其应用程序的影响。


1
请注意,“QoS消息永远不会被“升级”,因此,如果原始发布者发送了一个带有QoS 0的消息,那么QoS 2的订阅者仍将接收到QoS 0的消息”。更多信息请参见https://blog.famzah.net/2022/10/03/mqtt-qos-level-between-publisher-and-subscribers/。 - famzah

7
发布者其实不知道有哪些客户端订阅了那条消息。发布者的QoS级别决定了服务质量,以确保代理接收到该发布。一旦代理接收到该发布,就负责重新发送该消息。 [编辑] 然后代理将消息重新发送给订阅者,但最多只按照从发布者那里接收到的QoS级别。这甚至可能是对订阅者指定的QoS级别的降级。
我发现这篇文章在理解这个概念方面非常有帮助。

这不太对。 “QoS 消息永远不会‘升级’,因此如果原始发布者发送了一个 QoS 0 消息,则 QoS 2 订阅者仍将以 QoS 0 接收消息”。更多信息请参见 https://blog.famzah.net/2022/10/03/mqtt-qos-level-between-publisher-and-subscribers/。 - famzah
@famzah,我认错了。谢谢。我会修改我的回答。 - Deon McClung

2

“这是否意味着,发布者使用QOS 2发送消息,但是该消息可能不会到达客户端(QOS 0)?”

是的,这是正确的。 发布者希望以QOS 2发布,以确保记录仅在状态层到达一次(无重复)。为此,使用了一层重试和确认机制。提供主题给订阅客户端的代理还需要额外的工作,以确保按照请求的QOS级别传递消息。

例如,消息以QOS 1发布,并且同一主题的订阅者订阅了QOS 2,则处理将消息传递到该订阅者的代理必须确保不会向客户端发送重复消息。

在您的示例中,发布者使用QOS 2进行发布,因此状态层只插入了一次记录,而此同一主题有一个QOS 0的订阅者。该订阅者可能永远不会收到此消息。例如,在发送消息期间出现了网络故障,记录从未到达。由于QOS 0中没有确认机制,代理不会尝试重新传递。


QoS消息永远不会“升级”,因此,如果原始发布者发送了一个带有QoS 1的消息,那么QoS 2订阅者仍将接收到QoS 1的消息。更多信息请参见https://blog.famzah.net/2022/10/03/mqtt-qos-level-between-publisher-and-subscribers/。 - famzah

-3
我还没有阅读MQTT协议规范,只是在使用mosquitto 1.5.3进行测试。
1. 运行mosquitto服务器/代理
使用默认配置。
mosquitto -v

1541075091: mosquitto version 1.5.3 starting
1541075091: Using default config.

2. 发布测试消息

AAA sub topic 'aaa'
BBB sub topic '+'
DDD pub topic 'aaa'

3. 服务器标准输出

1541075322: New connection from 10.1.1.159 on port 1883.
1541075322: New client connected from 10.1.1.159 as DDD (c1, k60).
1541075322: No will message specified.

1541075322: Sending CONNACK to DDD (0, 0)
1541075322: Received PUBLISH from DDD (d0, q1, r1, m1, 'aaa', ... (8 bytes))
1541075322: Sending PUBACK to DDD (Mid: 1)

1541075322: Sending PUBLISH to AAA (d0, q0, r0, m0, 'aaa', ... (8 bytes))
1541075322: Sending PUBLISH to BBB (d0, q0, r0, m0, 'aaa', ... (8 bytes))
1541075322: Received DISCONNECT from DDD
1541075322: Client DDD disconnected.

在发布消息之前,服务器向DDD发送PUBACK

4. 所以我猜

pub qos=1只确保代理接收到消息,
sub qos也是如此:

[ pub ] ---pub_qos---> [ broker ] ---sub_qos--> [ sub ]

// MQTT客户端和代理网络拓扑是星型网络。
// 如果我有时间,我会阅读协议规范。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接