消息总线 vs. 组播

5
我正在开发一个应用程序,它由多个模块组成,并需要它们相互共享信息。例如:一个发布/订阅场景,其中一个模块发布一些信息(例如状态变量),而对该特定信息感兴趣的模块获取它。或者一个请求/响应场景,其中感兴趣的模块明确地询问信息并得到回答。
我一直在研究不同的消息总线实现,包括D-busØMQRabbitMQQPID(后两者基于AMQP)。然而,有人指出,与其尝试使用复杂而笨重的消息总线实现,为什么不简单地使用组播来解决问题呢。
由于缺乏经验,无法确定组播是否真正可以解决我的问题,也无法理解两种解决方案的利弊,因此恳请专家帮助我。非常感谢。

您有什么消息速率、大小、持久性和可靠性要求? - Scott A
@ScottA。大约有30个模块需要共享信息。消息速率并不是非常高。主要需要将状态信息传达给其他模块,例如当状态发生变化或者当一个模块请求状态变量的值时。在发布/订阅场景中,可靠性不是一个大问题,但在请求/回复场景中则是。 - Jahanzeb Farooq
共享状态中保存了多少信息?对于Zookeeper来说,使用情况是高读取、低写入、相当小的数据量。它不是一个消息传递系统,但可以被滥用为一个。 - Scott A
2个回答

8
有着在大规模、高并发生产环境中使用消息总线和组播的经验,并与多位有经验的网络工程师讨论过相关问题,我可以说,除非你要广播到大量节点(数百个),否则应该像瘟疫一样避免使用组播。
如果你打算使用组播,必须了解它是一种不可靠的协议。消息可能丢失、重复等。你需要花费很多时间来确保在组播之上的可靠性协议(重试、重复检测、重发等)正确无误,才能使其有用。有一个很好的故事,关于军队测试命令控制机器人坦克的组播的,我正在寻找参考资料……基本上当你向一行坦克发送 “右转90度、右转90度、开火” 的消息时,有些坦克只收到了一个“右转”消息,而其他坦克则收到了三次,这就是制造混乱的配方。
根据你需要共享的信息类型,有几种选项。
如果他们正在共享配置信息,请查看 Zookeeper 等工具。它可靠、轻量级、易于使用。共享状态的最新值始终可用并持久化。使用消息总线时,您仍然需要具备重传协议,以防止您的模块错过了上次的配置消息。
关于消息总线,它们可以很复杂。但是,我不会将 ZeroMQ 必然归入这一类别。它可以模拟消息总线,但更多是点对点机制。我没有在生产中使用它,但是我所做的研究和原型设计都非常有利。
另一个选择可能是像 Oracle Coherence、GridGain 和 GigaSpaces 这样的分布式数据网格。同样,这是另一个需要安装和维护的应用程序,因此你的复杂度会增加,但对于数据网格有许多用途。
另一个 MQ 选项是 HornetMQ。我没有使用过它(我们在内部使用两个商业 MQ:Sonic 和 MQ Series),但我看到了一些有利的比较。
D-Bus 似乎针对单台计算机上的通信进行了优化,并建议如果要进行点对点、集群或类似的事情,请寻找其他选项。重要提示:我从未使用过 D-Bus,所以我基本上只是复述我刚读到的信息。

非常感谢您的有益回复。这些模块需要共享大部分状态信息。我一定会研究一下Zookeeper。不幸的是,由于软件大小成为问题,因为它必须在内存和CPU资源有限的硬件上运行,所以无法考虑您提到的其他解决方案。 - Jahanzeb Farooq
@JahanzebFarooq Zookeeper的占用空间可能与HornetMQ类似。再次强调,这取决于你要交换什么内容。状态信息绝对是Zookeeper使用案例之一。如果你正在寻找轻量级的解决方案,ZeroMQ也是一个不错的选择,但它需要你在其上添加重新发送协议。需要有多少台机器进行通信? - Scott A
在典型情况下,所有模块都在同一主机上。但在更高级的情况下,某些模块需要在不同的主机之间通信,主机数量可能从10到50不等。 - Jahanzeb Farooq

1

你是否担心数据包或消息会被丢失?消息总线可以处理或减轻这些问题,而组播默认情况下则不能。


2
这似乎应该是一条注释。在回答问题之前,请通过注释收集您需要的任何澄清信息。 - Jonathan Dickinson

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