如何避免丢弃消息zeromq pub sub

时间:2013-08-02 03:50:15

标签: c++ zeromq publish-subscribe

我已经看到了几个关于此的问题,但没有一个我得到满意的答案。这个问题,zeromq pattern: pub/sub with guaranteed delivery特别相似,但我愿意使用任何其他zeromq机制来达到同样的效果。

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

需要这个的原因:

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

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

我认为另一种选择是在事后处理错过的消息,但这会浪费处理时间以后会丢弃的事件。

编辑: 我想进一步思考这个问题,我现在期望发送一条消息=消息传递,因为我正在使用inproc并在线程之间进行通信。但是,如果我通过tcp发送消息,即使ZeroMQ没有故意丢弃它,也有可能丢失消息。这是否意味着即使我使用阻止发送,我可能还需要处理丢弃的消息?是否有关于使用inproc进行邮件传递的保证?

2 个答案:

答案 0 :(得分:5)

总的来说,我认为无法通过0MQ为pub / sub提供保证。如果你真的需要完全可靠的消息传递,那么你将不得不自己动手。

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

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

0MQ指南提供了一些关于如何处理至少部分内容的想法here

答案 1 :(得分:5)

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

  

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

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

  

对于使用inproc进行邮件传递是否有任何保证?

嗯,有一点是有保障的;你没有处理物理套接字,因此消除了任何网络问题。