Linux 如何在ZeroMQ PUB-SUB模式中检查发送时是否由于HWM而丢弃消息

Linux 如何在ZeroMQ PUB-SUB模式中检查发送时是否由于HWM而丢弃消息,linux,ipc,zeromq,Linux,Ipc,Zeromq,我使用ZeroMQ(更具体地说是CZMQ)在Linux中为IPC实现了一个消息总线。这就是我所实施的 我的问题是,当发布服务器缓冲区已满时,我如何知道send已丢弃消息? 在我的简单测试设置中,我使用带有代理的发布服务器订阅服务器。我有一个快速的发送者和一个非常缓慢的接收者,导致消息击中HWM并在发送时丢弃。我的例外是,发送将失败,并出现“message dropped”错误,但事实并非如此。即使消息被删除,zmq\u msg\u send()也没有给我任何错误(我可以通过查看订阅端消息中的间隙

我使用ZeroMQ(更具体地说是CZMQ)在Linux中为IPC实现了一个消息总线。这就是我所实施的

我的问题是,当发布服务器缓冲区已满时,我如何知道send已丢弃消息?

在我的简单测试设置中,我使用带有代理的发布服务器订阅服务器。我有一个快速的发送者和一个非常缓慢的接收者,导致消息击中HWM并在发送时丢弃。我的例外是,发送将失败,并出现“message dropped”错误,但事实并非如此。即使消息被删除,
zmq\u msg\u send()
也没有给我任何错误(我可以通过查看订阅端消息中的间隙来验证这一点)


我怎么知道邮件何时被删除?如果这是预期的行为,并且ZeroMQ不让我们知道,那么如果我的send删除了消息,有什么解决方法可以找到呢

默认情况下,最近版本的zeromq发布/订阅默认为1000条消息的高水位
ZMQ_SNDHWM
/
ZMQ_RCVHWM

这意味着,如果你在一个紧密的循环中突发超过1000条消息,它可能会丢失一些。编写一个测试并为每条消息提供一个带有序列号的有效负载是很简单的

一个选项是将两个HWMs都设置为0。这意味着它是无限的

您可以使用我最近编写的一些示例来处理此问题:


将在一系列消息中在tport上发布和订阅。如果你玩HWM,你会发现如果它不是0,它会下降很多,你似乎要求的是发布/订阅并不理想的容错性。不仅可以达到HWM,而且考虑如果订阅客户端死亡并重新启动会发生什么,它会错过发布者发送的消息的持续时间。不管好坏在zmqv2中,PUB/SUB的默认HWM是无限的,但在v3中更改为1000,因为消息排队的速度快于发送的速度,导致系统内存阻塞。当平均消息速率在网络带宽内时,1000似乎是突发消息的合理值。YMMV


如果您只想知道消息何时被删除,那么只需向消息中添加一个递增的消息编号,并让订阅者监视即可。你可以选择把这个号码放在它自己的相框里,也可以不放;整体的简单性将是决定因素。我认为无法确定消息何时被丢弃,因为HWM已经到达。

谢谢@easytiger。我按照您的建议,特别是在指南中,添加了一个序列号,以解决用户速度慢的问题。但是我的用例有点不同。我真的不在乎订户;我想让我的发布者知道他是否因为点击了HWM而删除消息。合理的关注点。考虑到PUB/SUB的op,我认为应该将其默认为无穷大,并设置一个回调机制,在到达软水印时通知您,以便您可以创建应用程序逻辑来应对这种情况。我想这一切都取决于消费者的速度/并行性/可扩展性以及对100%可靠性的需求。大多数使用PUB/SUB的应用程序不需要100%的可靠性,因此我认为这是一种设计选择。我想知道用套接字注册回调以在特定队列大小上调用会不会很难?你的意思是绕过ZeroMQ层并在Linux套接字级别设置/检查队列大小?我的意思是向ZeroMQ添加功能以允许你在它决定删除任何内容时获得回调。我认为这需要一些工作,所以我不愿意这样做触摸零MQ库;官方的“这将使更新更难”的原因(真正的原因是懒惰)。谢谢@john。正如我在上面的回复中所提到的,我考虑按照您的建议添加序列号,特别是在指南中。但是我的用例有点不同。我真的不在乎订户;我想让我的出版商知道他是否因为点击了HWM而删除了邮件。我想你是对的;酒吧酒吧可能不是满足我需求的最佳模式。我想我必须在ZeroMQ传输的基础上建立应用程序的可靠性。@John>“当平均消息速率在网络带宽内时,1000似乎是突发消息的合理值。”这绝对不是真的。zeromq的要点是,这样您就不必向应用程序添加ringbuffers&2个线程。即使这样,我也很确定,在我开始加入pub/sub之前,我的10GB NIC还远远没有达到zeromq读取饱和的程度