如何避免丢弃消息zeromq pub sub

use*_*100 3 c++ publish-subscribe zeromq

我已经看到了几个关于此的问题,但没有一个我得到满意的答案.这个问题,zeromq模式:具有保证传递的pub/sub是类似的,尽管我愿意使用任何其他zeromq机制来实现相同的效果.

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

需要这个的原因:

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

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

我认为另一个替代方案是在事后处理错过的消息,但这只会浪费处理时间以后将被丢弃的事件.

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

Ste*_*ove 5

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

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

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

该0MQ手册里有关于如何去你想要什么,至少部分的一些想法在这里.


raf*_*ian 5

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

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

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

是否有关于使用inproc进行消息传递的保证?

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