了解 mqtt 订阅者 qos

Posted

技术标签:

【中文标题】了解 mqtt 订阅者 qos【英文标题】:Understanding mqtt subscriber qos 【发布时间】:2016-02-02 12:28:51 【问题描述】:

我是 MQTT 新手,刚刚了解了消息发布时决定的 QOS 级别的含义:

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

我注意到订阅方也可以设置“他们将收到的最大 QOS 级别”。 引用here:

例如,如果一条消息以 QoS 2 发布,而客户端以 QoS 0 订阅,则该消息将被传递到 QoS 0 的客户端。

这是否意味着尽管发布者使用 QOS 2 发送消息,但消息可能无法到达客户端 (QOS 0)?

这对于没有经验的开发者来说可能是个大问题——例如npm mqtt package中订阅功能的默认QOS是0! (在我看来,默认应该是最大值2,即“让发布者决定QOS”)。

【问题讨论】:

【参考方案1】:

你是对的,不能保证以 QoS 2 发布的消息会到达使用 QoS 0 的订阅者。如果订阅者接收消息很重要,他们应该使用 QoS 1 或 2。这是任何给定应用程序需要决定的事情。

我会将您对 QoS 0 的定义改写为“最多一次”,即消息将被接收或不被接收,没有重复的机会。

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

【讨论】:

【参考方案2】:

发布者对于哪些客户订阅了该消息并没有直接的概念。发布者的 QOS 级别决定了确保代理接收发布的服务质量。一旦代理接收到发布,it 将负责以相应订阅者选择的 QOS 将消息重新发送给每个订阅者。订阅者可以在 QOS 2 接收来自代理的消息,即使发布者将消息发送到 QOS 0 或 1 的代理。

我发现this article 对理解这个概念很有帮助。

【讨论】:

【参考方案3】:

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

是的,这是真的。发布者希望在 QOS 2 上发布,以确保记录仅到达状态层一次(没有重复)。一层重试+确认用于确保这一点。将主题提供给订阅客户端的代理需要做额外的工作,以确保消息以请求的 QOS 级别传递。

例如,一条消息在 QOS 1 发布,而同一主题的订阅者在 QOS 2 订阅,那么处理向所述订阅者传递消息的代理将必须确保没有重复发送给客户端。

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

【讨论】:

【参考方案4】:

我还没有阅读 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.

PUBLISH 消息之前将服务器PUBACK 发送到DDD。

4。所以我猜

pub qos=1 只确保经纪人收到了消息,sub qos 还有:

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

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

【讨论】:

以上是关于了解 mqtt 订阅者 qos的主要内容,如果未能解决你的问题,请参考以下文章

EMQ 学习---MQTT消息QoS

MQTT---HiveMQ源码详解(十六)TopicTree

MQTT协议探究

PAHO MQTT Python 客户端 - 缺少确认,保证为订阅者交付

MQTT 协议学习:006-订阅主题

Jmeter做MQTT测试(等待订阅,订阅内容获取)