4

我已经看到了几个关于此的问题,但没有一个我认为令人满意的答案。这个问题,zeromq 模式:特别是保证交付的 pub/sub 是相似的,尽管我愿意使用任何其他 zeromq 机制来实现相同的效果。

我的问题是,有什么方法可以像 ZeroMQ 中的发布者-订阅者那样以扇出模式发送消息,并保证消息将被传递?似乎零副本的经销商可以做到这一点,但它会比 pub-sub 更混乱。有更好的选择吗?除了必须编写更多代码之外,这样做的缺点是什么?

需要这个的原因:

我正在编写代码来分析来自仪器的数据。连接到仪器的模块需要能够将数据广播到其他模块以供他们分析。反过来,他们需要将分析的数据广播到输出模块。

乍一看,使用 ZeroMQ 的 pub-sub 似乎非常适合这项工作,但如果任何订阅者减速并达到高水位线,消息就会被丢弃。在此系统的情况下,由于事件连续性,消息仅在一小部分模块中被丢弃是不可接受的。所有模块都需要分析事件以使输出有意义。但是,如果没有模块收到事件的消息,那很好。因此,如果其中一个分析模块达到高水位线,则可以阻止发布者(检测模块)。

我想另一种选择是在事后处理丢失的消息,但这只会浪费处理稍后将被丢弃的事件的时间。

编辑:我想进一步考虑这一点,我目前期望一条消息已发送 = 消息已传递,因为我正在使用 inproc 并在线程之间进行通信。但是,如果我要通过 TCP 发送消息,即使 ZeroMQ 没有故意丢弃它,消息也有可能丢失。这是否意味着即使我使用阻塞发送,我也可能需要处理丢弃的消息?使用 inproc 传递消息是否有任何保证?

4

3 回答 3

6

一般来说,我认为 0MQ 无法单独为发布/订阅提供保证。如果你真的需要完全可靠的消息传递,你将不得不自己动手。

网络本质上是不可靠的,这就是为什么 TCP 进行如此多的握手只是为了让数据包通过。

与以往一样,这是延迟和吞吐量之间的平衡。如果您准备牺牲吞吐量,您可以自己进行消息握手 - 也许使用 REQ/REP - 并自己处理广播。

0MQ 指南有一些关于如何在此处至少完成您想要的部分内容的想法。

于 2013-08-02T11:22:38.557 回答
5

我同意史蒂夫。如果您真的需要 100% 的可靠性(或接近它),ZeroMq 可能不是您的解决方案。您最好使用商业消息传递产品,其中保证消息传递和持久性得到解决,否则,您将在 ZeroMq 中编写可靠性功能并可能在此过程中拉出您的头发。如果您需要应用程序和数据库之间的 ACID 合规性,您会实现自己的应用程序服务器吗?除非您想实现自己的事务管理器,否则您会购买 WebLogic、WebSphere 或 JBoss 来为您完成。

这是否意味着即使我使用阻塞发送,我也可能需要处理丢弃的消息?

我会远离明确阻止任何东西,它太脆弱了。如果消费端出现问题,同步发送方可能会无限期挂起。您可以使用轮询和超时来解决这个问题,但同样,它是脆弱和混乱的代码;坚持异步。

使用 inproc 传递消息是否有任何保证?

好吧,一件事是有保证的;您没有处理物理套接字,因此消除了任何网络问题。

于 2013-08-02T23:47:55.930 回答
0

这个问题出现在搜索引擎上,所以我只是想更新一下。

您可以在使用 PUB 套接字时阻止 ZeroMQ 丢弃消息。您可以设置ZMQ_XPUB_NODROP 选项,它会在发送缓冲区已满时引发错误。

有了这些信息,您可以创建类似死信队列的东西,如此所述,并继续尝试重新发送,中间有睡眠。

目前可能无法有效处理此问题,因为似乎没有办法在 ZeroMQ 中的发送缓冲区不再满时得到通知,这意味着定时休眠/轮询可能是找出发送是否发送的唯一方法队列再次有空间,因此可以发布消息。

于 2021-09-06T02:07:06.343 回答