MQTT 3.1.1 代理 QoS=1 ("at least once") 消息重新传递
MQTT 3.1.1 broker QoS=1 ("at least once") message redelivery
我正在尝试找出关于 MQTT 3.1.1 消息重新传递的真实情况,该消息由具有“至少一次”(QoS 1) 配置的 MQTT 订阅者接收:
- MQTT 代理是否重新传送来自订阅者的未确认的“QoS 1”消息?
- MQTT 代理重新交付之前必须经过多少时间?
- MQTT 代理是否不断尝试重新传送未确认的消息?
- 还有其他方法可以触发重新投放吗?
假设一个 MQTT 订阅者 没有用 PUBACK
消息响应接收到的 MQTT 消息,MQTT 代理需要(至少根据我的理解)重新传递必须“至少一次”接收的消息,直到订阅者为该消息发送 PUBACK
。
为了更具体地了解我想要实现的目标:
good/valid 推迟发送 PUBACK
直到接收到的消息被成功保存是一个想法 - 有效地提高了 QoS 级别,直到我的订阅应用程序保证消息被处理。
以及是否例如持久性错误(数据库超时)不会发送 PUBACK
,这将自动导致重新发送此类消息。
谢谢和最诚挚的问候
MQTT 代理是否重新传送来自订阅者的未确认的“QoS 1”消息?
来自[规范]:
When a Client reconnects with CleanSession set to 0, both the Client and Server MUST re-send any unacknowledged PUBLISH Packets (where QoS > 0) and PUBREL Packets using their original Packet Identifiers [MQTT-4.4.0-1]. This is the only circumstance where a Client or Server is REQUIRED to redeliver messages.
所以,是的,未确认的 QOS1 消息将被重新传送,但规范要求发生这种情况的唯一时间是客户端重新连接时。
虽然您具体说明您使用的是 MQTT v3.1.1,但我认为值得注意的是 MQTT v5 明确禁止除重新连接后的重新交付:
When a Client reconnects with Clean Start set to 0 and a session is present, both the Client and Server MUST resend any unacknowledged PUBLISH packets (where QoS > 0) and PUBREL packets using their original Packet Identifiers. This is the only circumstance where a Client or Server is REQUIRED to resend messages. Clients and Servers MUST NOT resend messages at any other time
MQTT 代理重新交付需要多长时间?
根据上述规范,自动重试不是必需的。一些代理可能会在一段时间后重新传输。 emqx supports this; mosquitto used to have an option but this was removed in version 1.5 with the change log 解释:.
Outgoing messages with QoS>1 are no longer retried after a timeout period.
Messages will be retried when a client reconnects. This change in behaviour
can be justified by considering when the timeout may have occurred.
- If a connection is unreliable and has dropped, but without one end
noticing, the messages will be retried on reconnection. Sending
additional PUBLISH or PUBREL would not have changed anything.
- If a client is overloaded/unable to respond/has a slow connection then
sending additional PUBLISH or PUBREL would not help the client catch
up. Once the backlog has cleared the client will respond. If it is not
able to catch up, sending additional duplicates would not help either
MQTT 代理是否不断尝试重新传送未确认的消息?
3.11 规范没有提供任何指导(因此,理论上是的)但是许多代理提供了一些对此的控制(排队消息的最大数量、队列的最大大小等)。
是否有其他方式触发重新投递?
是 - 断开并重新连接。
推迟发送 PUBACK 直到收到的消息被成功保存是一个 good/valid 想法吗
paho-dev group a couple of months ago. Its something that is being considered in the Go v5 Client 上对此进行了讨论(目前该客户端自动确认消息)。
需要注意的一件事是 MQTT 规范确实有关于 order acknowledgments are sent. Many clients ignore this requirement (and just send the acknowledgments whenever the handler returns) but some (e.g. the HiveMQ Java client) 排队 ACK 的要求,以便它们可以按正确的顺序发送。
我正在尝试找出关于 MQTT 3.1.1 消息重新传递的真实情况,该消息由具有“至少一次”(QoS 1) 配置的 MQTT 订阅者接收:
- MQTT 代理是否重新传送来自订阅者的未确认的“QoS 1”消息?
- MQTT 代理重新交付之前必须经过多少时间?
- MQTT 代理是否不断尝试重新传送未确认的消息?
- 还有其他方法可以触发重新投放吗?
假设一个 MQTT 订阅者 没有用 PUBACK
消息响应接收到的 MQTT 消息,MQTT 代理需要(至少根据我的理解)重新传递必须“至少一次”接收的消息,直到订阅者为该消息发送 PUBACK
。
为了更具体地了解我想要实现的目标:
good/valid 推迟发送 PUBACK
直到接收到的消息被成功保存是一个想法 - 有效地提高了 QoS 级别,直到我的订阅应用程序保证消息被处理。
以及是否例如持久性错误(数据库超时)不会发送 PUBACK
,这将自动导致重新发送此类消息。
谢谢和最诚挚的问候
MQTT 代理是否重新传送来自订阅者的未确认的“QoS 1”消息?
来自[规范]:
When a Client reconnects with CleanSession set to 0, both the Client and Server MUST re-send any unacknowledged PUBLISH Packets (where QoS > 0) and PUBREL Packets using their original Packet Identifiers [MQTT-4.4.0-1]. This is the only circumstance where a Client or Server is REQUIRED to redeliver messages.
所以,是的,未确认的 QOS1 消息将被重新传送,但规范要求发生这种情况的唯一时间是客户端重新连接时。
虽然您具体说明您使用的是 MQTT v3.1.1,但我认为值得注意的是 MQTT v5 明确禁止除重新连接后的重新交付:
When a Client reconnects with Clean Start set to 0 and a session is present, both the Client and Server MUST resend any unacknowledged PUBLISH packets (where QoS > 0) and PUBREL packets using their original Packet Identifiers. This is the only circumstance where a Client or Server is REQUIRED to resend messages. Clients and Servers MUST NOT resend messages at any other time
MQTT 代理重新交付需要多长时间?
根据上述规范,自动重试不是必需的。一些代理可能会在一段时间后重新传输。 emqx supports this; mosquitto used to have an option but this was removed in version 1.5 with the change log 解释:.
Outgoing messages with QoS>1 are no longer retried after a timeout period. Messages will be retried when a client reconnects. This change in behaviour can be justified by considering when the timeout may have occurred.
- If a connection is unreliable and has dropped, but without one end noticing, the messages will be retried on reconnection. Sending additional PUBLISH or PUBREL would not have changed anything.
- If a client is overloaded/unable to respond/has a slow connection then sending additional PUBLISH or PUBREL would not help the client catch up. Once the backlog has cleared the client will respond. If it is not able to catch up, sending additional duplicates would not help either
MQTT 代理是否不断尝试重新传送未确认的消息?
3.11 规范没有提供任何指导(因此,理论上是的)但是许多代理提供了一些对此的控制(排队消息的最大数量、队列的最大大小等)。
是否有其他方式触发重新投递?
是 - 断开并重新连接。
推迟发送 PUBACK 直到收到的消息被成功保存是一个 good/valid 想法吗
paho-dev group a couple of months ago. Its something that is being considered in the Go v5 Client 上对此进行了讨论(目前该客户端自动确认消息)。
需要注意的一件事是 MQTT 规范确实有关于 order acknowledgments are sent. Many clients ignore this requirement (and just send the acknowledgments whenever the handler returns) but some (e.g. the HiveMQ Java client) 排队 ACK 的要求,以便它们可以按正确的顺序发送。