用于本地/远程桥接的 MQTT 替代方案

物联网 MQTT
2021-06-18 04:27:51

在众多的 MQTT 问题中,我想知道当所有发送到主题的消息需要保留时,MQTT 有哪些替代方案,以及在新订阅者的队列中。

在我的公司,我们管理着远程部署,我们希望使用 MQTT 进行本地数据收集。这个想法是将数据发送到现场的本地代理(例如,在 Raspberry Pi 上运行),并且代理将拥有一个 MQTT 桥接器与我们的CloudMQTT部署。如果连接丢失,消息将在本地收集,并在重新建立连接时再次同步。

设置是典型的,如下所示:

简单的 MQTT 桥接

对于我的示例,左侧将是在每个位置运行的许多(大约 100 个)MQTT 本地代理,右侧将是我们支付的 CloudMQTT 服务器。

当我阅读文章MQTT Essentials Part 8: Retained Messages 时,这部分令人失望:

保留消息是一条普通的 MQTT 消息,保留标志设置为 true。代理存储最后保留的消息和该主题的相应 QoS。订阅与保留消息主题匹配的主题模式的每个客户端在订阅后立即收到保留消息。代理仅存储每个主题的一条保留消息。

本质上,这意味着 CloudMQTT 服务器上必须有一个订阅者,监听来自我们所有位置的所有传入事件;否则,数据可能会丢失。

MQTT 似乎只保留最新消息;是否有任何其他软件包可以执行此本地 <=> 远程同步,但保留所有消息?

4个回答

MQTT 会为您处理这个问题,保留消息不是正确的事情,您需要使用更高的QOS值(1 或 2 而不是默认的 0)。您需要阅读您提到的文章序列的第6 部分

保留消息解决了一个不同的问题,即允许新客户始终获取最新信息。高 QOS 将确保所有消息的传递。

您可以将 mosquitto 本地代理设置为以 QOS 1/2 桥接消息,而不管传感器发布的消息是什么。当网络出现故障时,代理会将所有消息排队,直到网桥返回,然后将它们传送到云代理。

您正在尝试使用不适合您的情况的系统。

MQTT 被设计为:

MQTT 是一种机器对机器 (M2M)/“物联网”连接协议。它被设计为一个非常轻量级的发布/订阅消息传输。

参考:https : //mqtt.org/

RabbitMQ 正是您要找的,它可以部署在分布式和联合配置中。它还有一个 MQTT 3.1.1 插件,随核心发行版一起提供。

参考:https : //www.rabbitmq.com

根据 MQTT 代理的支持,持久会话可能会起作用。当客户端连接时,他们可以将干净会话标志设置False,然后订阅感兴趣的主题。如果客户端失去连接,任何发布到 QoS 1 或 2 下的主题的消息都将排队。当客户端重新连接时,订阅将自动重新建立,队列中的消息已传递。

它确实需要对客户端进行更多的思考和潜在的更改来处理排队的消息。

另一种选择是创建您自己的服务来处理它。该服务需要连接到您指定的本地 RPi 上的本地 MQTT 代理(充当本地网关)。本地网关通常用于提供数据过滤,但您可以使用它来临时存储设备发送的数据。您可以使用 python 或任何支持 MQTT 客户端库的编程语言。客户端服务只不过是另一个运行在网关上的 MQTT 客户端,可以执行逻辑和数据库操作。您构建的这个客户端服务会在数据到达本地网关的 MQTT 代理时立即接收数据,尝试将其转发到 CloudMQTT。如果由于没有可用的 Internet 连接而无法连接到 CloudMQTT,它会将数据存储到带有标志的临时数据库,以跟踪该数据是否已发布到 CloudMQTT。客户端服务(始终在后台运行)尝试从数据库中获取此数据并重新发送。如果该数据成功发送到 CloudMQTT,该服务会在发送数据时更新该标志。您可以稍后从数据库中删除其标志值指示已发送到 CloudMQTT 的所有数据。因此,在这种情况下,您运行本地代理的本地 RPi 机器(当然与数据库类似SQLite ) 实际上可以充当智能网关。该解决方案应该使您能够发送所有收集的数据,即使在数小时甚至一天或更长时间没有 Internet 连接的情况下,因为您拥有所有备份。