使用 ZeroMQ 实现消息总线

Posted

技术标签:

【中文标题】使用 ZeroMQ 实现消息总线【英文标题】:Implementing a message bus using ZeroMQ 【发布时间】:2014-08-28 13:40:27 【问题描述】:

我必须开发一个消息总线,供进程相互发送、接收消息。目前,我们在 Linux 上运行,以便以后移植到其他平台。

为此,我在 TCP 上使用 ZeroMQ。模式是带有转发器的 PUB-SUB。我的总线作为一个单独的进程运行,所有客户端都连接到 SUB 端口以接收消息,并连接到 PUB 以发送消息。每个进程通过一个唯一的标签订阅消息。来自进程的send 调用向所有人发送消息。 receive 调用将获取该进程标记有该进程标记的消息。这工作正常。

现在我需要包装 ZeroMQ 的东西。我的客户只需要提供一个独特的标签。我需要维护标签与 ZeroMQ 上下文和套接字详细信息的全局列表。当客户说, initialize_comms("name"); 总线需要检查这个名字是否唯一,创建 ZeroMQ 上下文和套接字。同样,如果客户端说receive("name");,总线需要获取带有该标签的消息。

总结一下我面临的问题;

    有没有办法使用 ZeroMQ 提供的工具来实现这一点? ZeroMQ 是解决此问题的正确工具吗,还是我应该寻找类似 nanomsg 的工具? 带有转发器的 PUB-SUB 是正确的模式吗? 或者,我在这里遗漏了什么?

【问题讨论】:

您可以查看OMG DDS(数据分发服务)标准。从您的(简短)描述来看,它似乎很合适,并提供了您正在寻找的那种抽象。 我不完全清楚为什么 ZMQ 的正常订阅没有完全涵盖您想要做的事情。 @ReinierTorenbeek > 感谢您的指点。快速浏览一下,该理论非常适合我的想法,但似乎没有那么多开源实现。我会留意的。 @Jason > 实际上我对 ZeroMQ 很陌生,所以你可能是对的。为什么我选择带有 FORWARDER 的 PUB-SUB 是因为我不能使任何进程成为静态的。他们可以随心所欲地来来去去,所以我需要一个静态的接触点,而这正是 FORWARDER 适合的地方。 似乎是一个合理的选择。如果您还没有阅读the guide,我强烈建议您阅读...如果您有几周的时间以自然的速度完成它并在此过程中吸收它,它会回答您的大部分问题问题。特别是,您提到“创建 ZeroMQ 上下文”......通常每个进程只需要一个,并且所有套接字都属于该上下文。您可以将多个套接字连接到每个绑定套接字,因此您甚至可能不需要按需启动多个套接字。这样的事情可以极大地简化您的架构。 【参考方案1】:

答案

    是的ZeroMQ 能够满足这一需求

    是的ZeroMQ 是一个合适的工具(相当强大的低延迟组件工具箱)。虽然nanomsg 有一个直接的总线原语,但核心分布式逻辑可以集成到ZeroMQ 框架中

    是与否。上面给出的 PUB-SUB 可以用于模拟“shout-cast”到总线,并建立在使用订阅密钥的 SUB 副作用之上。必须重新考虑和设计逻辑的整个 REST,以便整个制造范围符合您的计划(参考下文)。还请记住,ZeroMQ 的初始版本操作 PUB/SUB 原语作为在接收方完成的传入消息流的“订阅过滤”,因此大规模设计应检查 traffic-volumes / risk-of-大规模的洪水/流程效率低下......

    是的ZeroMQ 是一个经过良好调整的原始元素基础(就架构的讨论而言,而不是其功能和性能),以构建更聪明、更健壮和几乎线性可扩展的正式通信模式。一旦草绘架构,就不要拘泥于 PUB/SUB 或 PAIR 基元。 如果忘记了真正的力量从何而来,任何设计都会变得糟糕。

是迈向可扩展且具有故障恢复能力的总线的下一步的好地方

因此,最好的下一步是恕我直言,以获得更多的全局视图,这对于尝试使用 ZeroMQ 编码的前几件事来说可能听起来很复杂,但如果您 at least jump to the page 265 Code Connected, Volume 1,如果不是这样一步一步地阅读的话。

有史以来最快的学习曲线是首先在 图 60 重新发布更新图 62 上获得未公开的视图strong> HA 克隆服务器对实现可能的高可用性方法,然后回到根源、元素和细节。

【讨论】:

感谢您提供的信息并为我指明正确的方向。我已经开始看书了。到目前为止,我在这里和那里参考了这本书,但这是我第一次一步一步地阅读它。整理好后我会发布更新。 @Raggs > 很高兴听到这个消息,Raggs。书中的故事永远不会从典型的手册页“组装”,更不用说来自 URL-HyperSpace 中的 code-sn-ps。 在撰写此评论时,此答案中包含的所有链接都返回 404(未找到)。【参考方案2】:

这是我最终设计的,如果有人感兴趣的话。感谢大家的提示和指点。

    我有一个使用 ZeroMQ(和 CZMQ)作为单独进程运行的消息总线。 模式是带有 LISTENER 的 PUBLISHER-SUBSCRIBER。它们使用代理连接。 此外,还有一个使用新分支线程调用的 ROUTER。 这三个端点在 TCP 上运行,并绑定到客户端知道的预定义端口。 PUBLISHER 接受来自客户端的所有消息。 SUBSCRIBER 向已订阅该标签的客户端发送带有唯一标签的消息。 LISTENER 监听所有通过的消息。目前,这是为了记录测试和目的。 ROUTER 为客户端提供单独的通信通道。诸如控制命令之类的消息被定向到这里,这样它们就不会被传递到下游。 客户端连接到,
      PUBLISHER 发送消息。 订阅接收消息。订阅使用了唯一标签。 ROUTER 发送命令(检查标签唯一性等)

我仍在执行,因此可能存在看不见的问题,但现在它工作正常。另外,可能还有更优雅的方式,但我不想扔掉我构建的 PUB-SUB 东西。

【讨论】:

这是一个闭源项目吗? 不幸的是,是的。但如果可能的话,我很乐意以任何方式帮助你。 @fortytwo thnx 分享

以上是关于使用 ZeroMQ 实现消息总线的主要内容,如果未能解决你的问题,请参考以下文章

Linux进程内消息总线设计

实现消息总线架构

Bus:消息总线

Bus:消息总线

MassTransit一个优秀的.NET消息(事件)总线框架

MassTransit一个优秀的.NET消息(事件)总线框架