我有一对ZeroMQ ROUTER
/ DEALER
形式的正式通信原型,用于两台计算机之间的异步通信。
如果带有DEALER
插槽的计算机脱机一段时间并返回,则会丢失一些消息。
我知道ZeroMQ无法无限期地保留消息,因为无法保证DEALER
方面会回来。我正在寻找配置此行为的方法 - 是否有一个设置可用于控制消息在放弃之前保留多长时间?
哪些设置可能会影响此行为?
我不认为该问题与高水位标记设置的值有关,因为传输的数据量非常低。
Windows上的ZeroMQ版本4.0.4。
我不确定要显示的代码的相关部分究竟是什么。此外,将事情脱离背景并使其易于理解并非完全直截了当。我会试试,所以这里。
这是路由器套接字的初始化方式:
router-socket (doto (zmq/socket zmq-context :router)
(zmq/set-receive-timeout 100)
(zmq/set-recv-hwm 0)
(zmq/set-send-hwm 0)
(zmq/bind (str "tcp://*:" (:port request-handler))))
发送消息使用zmq / send函数。
即使没有clojure经验,zeromq部分也应该清晰。
以下是经销商的初始化方式(C#):
var dealer = context.CreateSocket( SocketType.DEALER );
dealer.SendHighWatermark = 0;
dealer.ReceiveHighWatermark = 0;
消息的接收使用ZmqSocket.ReceiveMessage方法(实际上,它是SendReceiveExtensions类中的扩展方法,但无论如何)。
发生包裹丢失的一个(可能是主要的)情况是运行经销商的计算机进入睡眠状态(=笔记本电脑盖关闭)并且在几分钟之后被唤醒。就像我在原始问题中所说的那样,我假设由于路由器暂时放弃经销商回来因此丢弃消息而丢失了包裹。但这只是一个假设,原因可能也是其他原因。
因此,让我们从ZeroMQ Context()
引擎设置开始,这是使用.setsockopt()
方法的功能运行ZeroMQ中智能信令/消息传递的所有低级功能的最终权限。
对于真实世界的故障排除,没有任何东西像一个通用的所有,所以没有上面的任何代码,有许多事情可以通过猜测和过去的麻烦的经验来接近,一个人已经遇到。
虽然一些根本原因可能实际上被ZeroMQ流程的其他习惯所掩盖,但是在下面的文本中,下面的文字更多地是关于平衡行为艺术的尽可能广泛的观点,而不是一步一步。 - 步进导航。
从上面的一些评论开始,将从这些嫌疑人开始,从众多智能API选项中:
ZMQ_RECONNECT_IVL
:设置重新连接间隔
ZMQ_RECONNECT_IVL
选项应设置指定套接字的初始重新连接间隔。重新连接间隔是ØMQ在使用面向连接的传输时尝试重新连接断开的对等体之间应等待的时间段。
从~ 100 [ms]
缩短到一些2 [ms]
,调整后的ZMQ_RECONNECT_IVL_MAX
到其几倍,可以与下面提到的用于幸存的虚假LoS和类似服务丢失的策略一起帮助在更新丢失的低级连接时减少开销延迟。
参考。也可以通过ZMQ_TCP_MAXRT
进行ZMQ_TCP_KEEPALIVE_{CNT | IDLE | INTVL}
和O / S覆盖(可在O / S支持的地方使用)。
当没有连接对等体时,这个将突出显示状态,以便可以针对用户应用程序代码中的这些观察到的情况调整消息传递策略:
ZMQ_IMMEDIATE
:仅将消息排入已完成的连接默认情况下,即使连接尚未完成,队列也将填充传出连接。这可能导致使用循环路由(
REQ
,PUSH
,DEALER
)的套接字上的“丢失”消息。如果此选项设置为1,则消息应仅排队到已完成的连接。如果没有其他连接,这将导致套接字阻塞,但会阻止队列填充等待连接的管道。
使用类似的策略,如上面针对DEALER
方面发布的那样,ROUTER
方可以使用ZMQ_PROBE_ROUTER
设置,以便引导到ROUTER
套接字的连接
如果主要是可能的,并且如果成本方面仍然合理,可以使用一种“服务”声纳 - 哔哔声,定期注入:
ZMQ_HEARTBEAT_IVL
:设置发送ZMTP心跳之间的间隔
ZMQ_HEARTBEAT_IVL
选项应设置为指定套接字发送ZMTP心跳之间的间隔。如果此选项已设置且大于0,则每隔ZMQ_HEARTBEAT_IVL
毫秒发送一个PING ZMTP命令。
ZMQ_HEARTBEAT_TIMEOUT:
为ZMTP心跳设置超时
ZMQ_HEARTBEAT_TIMEOUT
选项应设置在发送PING ZMTP命令并且没有接收任何流量之后等待连接之前等待的时间。此选项仅在ZMQ_HEARTBEAT_IVL
也设置且大于0时有效。如果在发送PING命令后没有收到流量,则连接将超时,但接收的流量不必是PONG命令 - 任何接收的流量将取消超时。
ZMQ_HEARTBEAT_TTL
:设置ZMTP心跳的TTL值
ZMQ_HEARTBEAT_TTL
选项应为ZMTP心跳设置远程对等体的超时。如果此选项大于0,则远程端如果在TTL周期内没有再接收到任何流量,则应使连接超时。如果未设置ZMQ_HEARTBEAT_IVL
或为0,则此选项无效。在内部,此值向下舍入到最接近的十分之一,任何小于100的值都将无效。
ZMQ_CONNECT_TIMEOUT
:设置connect()
超时设置在超时
connect()
系统调用之前等待的时间。connect()
系统调用通常需要很长时间才能返回超时错误。设置此选项允许库以较早的时间间隔超时。
设置几个[ms]
可能有助于消除间歇性中断和/或在它们之间打开新的服务窗口。为了允许这种短窗策略工作,还应该减少ZMQ_HANDSHAKE_IVL
允许的最大值。
ZMQ_BACKLOG
:设置未完成连接队列的最大长度
ZMQ_BACKLOG
选项应设置指定套接字的未完成对等连接队列的最大长度;这仅适用于面向连接的传输。有关详细信息,请参阅listen
函数的操作系统文档。
这里有一百个可以提供足够的服务,但是没有关于“丢失”连接数量的详细信息,让我们将其保留在故障排除者的购物清单上。