不要订阅# - 那么如何使用 Mosquitto 将所有消息转储到数据库?

物联网 MQTT 蚊子
2021-06-02 23:06:05

HiveMQ 的博客在“最佳实践”下列出了在尝试将所有消息转储到数据库时不要订阅多级通配符。他们声称订阅客户端可能无法跟上高负载的消息,并建议使用代理插件直接挂钩消息流。

有时需要订阅通过代理传输的所有消息,例如将所有消息持久化到数据库中时。这不应通过使用 MQTT 客户端并订阅多级通配符来完成。原因是订阅客户端通常无法处理即将到来的消息负载。特别是如果你有大量的吞吐量。我们推荐的解决方案是在 MQTT 代理中实现一个扩展,例如 HiveMQ 的插件系统允许您挂钩 HiveMQ 的行为并添加一个异步例程来处理每个传入的消息并将其持久化到数据库中。

有没有

  • mosquitto 代理的类似系统(扩展/插件),
  • 另一种适用于蚊子的推荐方法,或
  • 合理的证据表明这种方法根本没有必要,即订阅的客户#可以做得很好?

https://stackoverflow.com/q/31584613/3984613没有详尽地解决这个问题。

3个回答

mosquitto 代理的类似系统(扩展/插件)

据我所知,mosquitto 代理没有插件/扩展(至少没有开源)

另一种适用于 mosquitto 的推荐方法

好吧,我可以说,根据我在 Mosquitto 代理和 AWS IoT 方面的经验,您可以直接订阅“#”

合理的证据

看完这个问题,我有点好奇想知道吞吐量限制,看看是否需要一个扩展系统。所以我设置了以下内容:

  • 100 个 AWS Lambda 函数充当虚拟终端设备将一些随机数据发送到网关(EC2 实例t2.nano500MB RAM)
  • 每 60 秒触发一次函数将数据发布到不同主题的网关 ( lambdatoec2/{VariableTopicNumberFrom1-100}
  • EC2 实例正在运行 Mosquitto 1.4.10

到目前为止,我看到订阅 # 没有任何扩展系统没有问题。但是我仍然需要测试一些边缘情况(我会在测试它们后更新答案)。

openHAB 邮件列表上的这个讨论似乎表明使用#订阅接收所有消息没有问题

在对 MQTT 设备进行故障排除时,我突然想到,有时我希望我可以看到 Mosquitto 代理看到的所有 MQTT 消息,而不是关于特定主题的消息。有没有办法做到这一点?

在 Mosquitto 名单上有人为你回答了这个问题;使用通配符。(#)

这个 Stack Overflow 问题也提出了同样的方法:

订阅 # 可以让您订阅所有内容,但以 $ 开头的主题除外(无论如何,这些主题通常都是控制主题)。

当然,最好先了解您要订阅的内容,并注意某些代理配置可能不允许显式订阅 #。

正如Bence Kaulics所指出的该规范确实指出这#是有效的:

非规范性评论

  • “#”是有效的,会收到每一条申请消息

老实说,我怀疑最初的主张是否真的有多大意义:

原因是订阅客户端通常无法处理即将到来的消息负载。

如果是这种情况,代理首先如何处理消息?只要您的客户端具有与代理相似的性能特征,我强烈怀疑是否有可能使客户端不堪重负,因为该级别的流量也会使代理不堪重负并导致其首先崩溃。

总之,HiveMQ 声明似乎没有得到来自其他来源的大量证据的支持,当您考虑它的实际含义时,它似乎并不特别合乎逻辑。

我认为重要的是要考虑到 MQTT 代理有许多不同的用例,就像任何软件一样。

处理十亿用户的聊天消息(用户多,每个用户的消息率相对较低)与客户端少但消息率高的系统不同,它们都不同于家庭自动化系统(客户端少,消息率低) .

HiveMQ 正在考虑非常高的客户端/消息速率应用程序 - 在这种情况下,代理的能力几乎肯定远远超过客户端的能力。

如果您想订阅#您的家庭自动化系统,那么它真的不太可能引起问题。在任何情况下,您都可以检查代理是否使用过多的 CPU。

与其他答案一样,订阅#将为您提供所有“正常”主题,即任何不以$. 我将规范解释为每个主题开头$都是一棵独立的树,因此您必须订阅$SYS/#$whatever/#才能获得所有内容对于普通应用程序,您很可能不想这样做。