【问题标题】:0MQ: Can you drop a message after a timeout in a REQ/REP pattern?0MQ:您可以在 REQ/REP 模式中超时后丢弃消息吗?
【发布时间】:2020-02-21 02:30:22
【问题描述】:

在我的 0MQ 应用程序中,我通常这样做是为了处理超时:

import zmq

ctx = zmq.Context()

s = ctx.socket(zmq.DEALER)
s.connect("tcp://localhost:5555")

# send PING request
v = <some unique value>
s.send_multipart(["PING", v])
if s.poll(timeout * 1000) & zmq.POLLIN:
    msg = s.recv_multipart()
    ...

但是,如果服务器没有运行并且几分钟后上线,那么 0MQ 将自动重新连接并发送消息。 但是,如果我将 send PING 命令 放在一个循环中(每秒一次)并且 服务器已关闭,然后一旦服务器重新上线,我将继续下一个recv_multipart()-调用旧消息 当服务器离线时,它仍保留在内部 0MQ 队列中。因为我不在乎老 消息,我虽然可以这样做:


s = ctx.socket(zmq.DEALER)
s.connect("tcp://localhost:5555")

while True:
    # send PING request
    v = <some unique value>
    s.send_multipart(["PING", v])
    if s.poll(timeout * 1000) & zmq.POLLIN:
        msg = s.recv_multipart()
        ...
    else:
        s.close()
        s = ctx.socket(zmq.DEALER)
        s.connect("tcp://localhost:5555")

    time.sleep(1)

但这是个坏主意,一段时间后ctx.socket 引发ZMQError: Too many open files。 将ZMQ_LINGER 套接字选项设置为 0 似乎有帮助 在这里,但现在我不喜欢这种策略,对我来说似乎是错误的。

所以理想情况下,如果读取超时,我想删除之前发送的消息 发生。这是a)可能和b)一个好主意吗?我不确定这 虽然是正确的,但可能是 0MQ 能够物理发送 消息,但服务器在它可以发回任何东西之前崩溃,所以丢弃 不可能,因为不会有任何东西可以掉落,不是吗?

所以我的问题是:在这种情况下我应该怎么做?我可能在看吗 这个问题从错误的角度?

【问题讨论】:

    标签: zeromq pyzmq


    【解决方案1】:

    Q“你能在REQ/REP 模式中超时后丢弃消息吗?”

    没有。

    Q这是 a) 可能的 b) 一个好主意吗?

    a) 是的。
    b) 是的。

    在这种情况下我应该怎么做?

    最好避免 REQ/REP 陷入相互僵局的确定性(你永远不知道它何时发生 - 这里有很多帖子) + 设置连接层,以便提供仅传递最后一条消息的自卫手段通过健康的连接:

    ...
    s = ctx.socket( zmq.DEALER )
    
    s.setsockopt( zmq.LINGER,    0 ) # ALWAYS, no excuse, you never know the peers' versions
    s.setsockopt( zmq.IMMEDIATE, 1 ) # prevent sending over incomplete yet connections
    s.setsockopt( zmq.CONFLATE,  1 ) # Does not support multi-part, so .pack() payload
    
    s.connect( "tcp://localhost:5555" )
    ...
    

    【讨论】:

    • 感谢您的回答,但我不确定我是否完全理解它。如果我设置了zmq.IMMEDIATE 套接字选项,那么是否意味着s.send 会阻塞,直到服务器真正在线?
    • send()-method 阻塞 if & "only" 如果您希望它阻塞,但仍然是在某些特定的本地 Context()-instance 条件下(有关此详细信息,请参阅 API)。专业系统永远不应该阻止(谁会希望失去对拥有的控制域的控制?你认为成为并保持没有任何机会改变这种状态是明智的吗?你的接受 powerless-ness“Powerlessness of Empowered”是一部不错的哲学著作,但让它出现在控制系统中?)避免任何阻塞{ .send() | .recv() }-methods 的形式,使用标志 zmq.NOBLOCK
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 2017-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多