ZeroMQ 反转 PUB/SUB 的问题

Posted

技术标签:

【中文标题】ZeroMQ 反转 PUB/SUB 的问题【英文标题】:Problems with Inverted PUB/SUB with ZeroMQ 【发布时间】:2011-08-11 09:25:34 【问题描述】:

我正在尝试使用 ZeroMQ 设置“反向”PUB/SUB。

表示订阅(SUB)socket属于几个长寿命服务器,做zmq_bind();并且发布 (PUB) 套接字是一个短暂的客户端,并且会执行 zmq_connect()

我使用单个 ipc:// 套接字。

我希望来自发布者的消息会到达每个订阅者。

问题:只有一个订阅者进程接收到消息。如果该进程终止,发布者会卡在zmq_term()

zmq 是否支持这种操作模式?如果是,那我做错了什么?如果没有,那么如何实现我需要的?

带有一些额外细节的最小示例(在 Lua 中,但这不重要):https://gist.github.com/938429

【问题讨论】:

【参考方案1】:

您不能将多个套接字绑定到一个ipc:// 地址(我们在这里讨论的是 Unix 域套接字 ipc:///tmp/test.ipc == file /tmp/test.ipc)。

您可以将每个 SUB 套接字绑定到不同的 ipc:// 地址,并让发布者将一个 PUB 套接字连接到每个地址。 ZeroMQ 允许一个套接字绑定/连接到多个地址。

zmq_term() 上的阻塞很可能是由于延迟关闭问题(即有一条消息表明 PUB 套接字正在尝试发送)。看看ZMQ_LINGER 套接字选项。

【讨论】:

是的,每次绑定都会覆盖文件。我应该自己想出来的,抱歉打扰了。 你不是第一个受到这个打击的人;它与其他传输方式完全不一致,因此并不明显......列表上已经讨论过如何改变它。【参考方案2】:

ipc:// 传输有一个“特性”,即如果两个进程绑定到同一个 IPC 端点,第二个进程会悄悄地从第一个进程中窃取绑定。此“功能”旨在让进程在崩溃后轻松恢复。

这就是为什么只有一个订阅者收到消息的原因。

既然您只有一个发布者,为什么不绑定发布者并将订阅者连接到该发布者?即使发布者来来去去,订阅者也会自动重新连接。

【讨论】:

【参考方案3】:

您不能将多个套接字绑定到一台机器上的同一地址,无论是 ipc 还是 tcp、SUB/PUB 或 REQ/REP。就像网络套接字的绑定一样。

从许多发布者向所有订阅者发送消息的方法是实现一个简单的代理,该代理绑定到一个 SUB 地址和一个 PUB 地址。发布者连接到 SUB 套接字发送消息,订阅者连接到同一个代理的 PUB 套接字,代理简单地将所有从 SUB 套接字接收到的消息转发到 PUB 套接字。它需要一些性能开销,但很容易编程。

在 ZeroMQ 2.0 中有一个可执行的 zmq_forwarder 可用于此目的,在 2.1 中请参阅 zmq_device(3) 函数。

【讨论】:

如果我理解正确,代理进程将是单点故障。有没有办法避免这种情况? 我想是的。但是由于您的所有程序都在一台计算机上运行(使用 ipc:// 套接字),因此硬件和网络故障不会成为问题。代理进程本身可能太简单而不会失败。但是,如果涉及到很多节点,我不确定这是否是最好的方法。 总有一只混沌猴,即使在一台机器上也是如此。 (开个玩笑:-)) 阅读 ZMQ 指南并大致了解如何构建所有各种通信可能性确实是值得的。 zguide.zeromq.org/page:all

以上是关于ZeroMQ 反转 PUB/SUB 的问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 ZeroMQ 使用 PUB/SUB 实现 Master/Worker 模式

ZeroMq PUB/SUB 模式无法正常工作

zeromq pub sub 上丢失的消息

消息队列、EventBus 和 Pub/Sub 之间的区别?

pub/sub : 如何使用 pub sub 查看任何电子邮件帐户中的消息?

zeromq使用模式实验总结