繁体   English   中英

ZeroMQ的可靠性?

[英]ZeroMQ reliability?

我一直在使用ZeroMQ的请求/响应套接字,以在Web应用程序和用于卸载处理的从属应用程序之间交换消息。 我注意到在某些情况下,并非所有发送的ZMQ消息实际上都被另一端接收到。 甚至奇怪的是,即使使用IPC协议,这种情况也会发生,我认为这是相当可靠的。

在不产生任何错误的情况下,导致未发送已发送消息的原因是什么?

这是客户端代码的示例:

# ironic
class ReliableClient(object):
    def _reconnect(self):
        if self.socket:
            self.socket.close()
            self.socket = None

        self.socket = self.context.socket(zmq.REQ)
        self.socket.connect(self.server_url)

        # Give the server 2 sec to respond
        self.socket.RCVTIMEO = 2000
        self.socket.SNDTIMEO = 2000

        self.socket.LINGER = 3

    def __init__(self, server_url=None, server_name=None):
        self.socket = None
        self.server_url = server_url

        if server_name is None:
            self.server_name = server_url
        else:
            self.server_name  = server_name

        self.lock = threading.Lock()
        self.context = zmq.Context()

        self._reconnect()

    def msg(self, msg):
        raw_out = dumps(msg)

        # send
        self.lock.acquire()
        try:
            self.socket.send(
                raw_out,
                copy=True
            )
        except zmq.ZMQError as ex:
            log.exception(ex, '%s: failed to send', self.server_name)
            self.lock.release()
            raise CommunicationError('failed to send')

        # receive
        try:
            raw_in = self.socket.recv()
        except zmq.ZMQError as ex:
            log.exception(ex, '%s: failed to receive', self.server_name)
            raise CommunicationError('failed to receive')
        finally:
            self.lock.release()

        msg_in = loads(raw_in)  

        return msg_in

我对IPC协议不熟悉,但是我已经广泛使用ZMQ / TCP。

如果正确使用TCP,即使是基于TCP的最简单的ZMQ REQ / REP模式也永远不会丢弃消息 如果您的网络连接或远程端点断开,它可能会无限期挂起,但它绝不会默默地失败。 在某些情况下,某些套接字在设计上会丢弃消息。 例如,某些邮件可能会在达到HWM时丢弃消息。

在不产生任何错误的情况下,导致未发送已发送消息的原因是什么?

如果您使用ROUTER套接字将中间消息从服务器发送到zmq工作进程,则默认情况下, ROUTER会丢弃它们无法传递的所有出站消息。 “无法交付”是什么意思? ROUTER维护客户端身份到客户端连接的内部映射,并且由于路由器上的所有消息都有一个身份(由客户端提供或由路由器自动分配),因此任何没有对应连接的出站消息都将与之建立关联。路线,将被静默掉落。

您可以通过告诉ROUTER报告无法传递的消息来确定何时发生这种情况,换句话说,ROUTER在无法传递消息时会生成错误。 在Java中,方法是routerSocket.setRouterMandatory(true) ,您只需要查找与此对应的python即可(我不是py家伙,哈哈)

如果您确定ROUTER正在丢弃消息,那么问题就变成了为什么? 在我的情况下,我有一个zmq客户端,它在不同的线程上发送和接收服务器消息,并且接收线程的连接速度不够快,无法满足服务器的初始“ Ok”响应,因此这只是服务器中的计时问题。客户。

希望能有所帮助

如果保证两个系统始终处于活动状态(24X7),或者仅在两个系统处于活动状态时才发送消息,那么ZeroMQ可以用作在系统之间传输小事件的一种极好的方法,是一种很好的选择。

由于订阅者速度较慢,我们在ZeroMQ pub-sub模式下发送大量消息时遇到问题,并且我们开始在中间丢失消息。 后来,我们转到ActiveMQ嵌入式代理模式,该模式将消息保留在内存中,直到使用者使用它们为止。 关于ZeroMQ的好处,即使没有发布者,或者发布者以后会出现,订阅者都可以启动。

Active MQ的限制,无法在Producer创建Queue之前开始从Queue读取消费者。 显然,它将引发异常。 我们还可以使用这两个库,并充分利用每个库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM