ZeroMQ 'Restart' 如果没有收到回复

ZeroMQ 'Restart' if no reply was recieved

我有一个 python 程序可以将高度数据从我的客户端发送到我的服务器程序。我的服务器程序不会总是 运行 所以如果我没有收到响应我希望它再试一次。

到目前为止,我所知道的是,如果在 20 秒内未给出(来自服务器的)响应,则会导致异常并撤回我的输入。它工作正常,直到我第二次尝试。

这是我的代码:

import zmq
from time import sleep

global radius
context = zmq.Context()
print("Remote Deployment Application")
print("Lightweight ZMQ Communication")
print("Connecting to Desk Ctrl Service")
socket = context.socket(zmq.REQ)
socket.connect("tcp://192.168.1.9:5555")
socket.setsockopt(zmq.RCVTIMEO, 30000)
socket.setsockopt(zmq.LINGER, 0) 


#  Do 10 requests,waiting each time for a response
def __init__(self, height):
        self.height = height

def start():
    global height
    height = input("Enter in request: ")
    SendHeightVal()


def SendHeightVal():
    global userinput
    global height
    print("Sent Request. Awaiting Reply.")
    so_bytes = height.encode()
    socket.send(so_bytes)
    so_bytes = 0
    try:
       message = socket.recv()
    except:
        print("Something went wrong. No response from server!")
        message = None       
        start()    
    print(message)
    start()

这里是错误:

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "client.py", line 44, in <module>
    start()
  File "client.py", line 22, in start
    SendHeightVal()
  File "client.py", line 37, in SendHeightVal
    start()
  File "client.py", line 22, in start
    SendHeightVal()
  File "client.py", line 30, in SendHeightVal
    socket.send(so_bytes)
  File "/usr/local/lib/python3.6/site-packages/zmq/sugar/socket.py", line 391, in send
    return super(Socket, self).send(data, flags=flags, copy=copy, track=track)
  File "zmq/backend/cython/socket.pyx", line 727, in zmq.backend.cython.socket.Socket.send
  File "zmq/backend/cython/socket.pyx", line 774, in zmq.backend.cython.socket.Socket.send
  File "zmq/backend/cython/socket.pyx", line 249, in zmq.backend.cython.socket._send_copy
  File "zmq/backend/cython/socket.pyx", line 244, in zmq.backend.cython.socket._send_copy
  File "zmq/backend/cython/checkrc.pxd", line 25, in zmq.backend.cython.checkrc._check_rc
zmq.error.ZMQError: Operation cannot be accomplished in current state

检查this,你会发现:

socket zmq.REQ will block on send unless it has successfully received a reply back.

这意味着在收到答复之前您不能发送另一个请求。 ZMQ 与您使用的客户端/服务器 zmq.REQ / zmq.REP.

具有不同的消息传递模式

Any attempt to send another message to the socket (zmq.REQ/zmq.REP), without having received a reply/request will result in an error:

....
socket.send ("Hello")
socket.send ("Hello1")
....

Error: zmq.core.error.ZMQError: Operation cannot be accomplished in current state

这就是您遇到异常的原因:

zmq.error.ZMQError: Operation cannot be accomplished in current state

让我们从强制功能的简单清单开始:

" [agent-A] sends height data from my client to my server program. My server program [agent-B] will not be always running so if I don't receive a response I would like it [agent-A] to try again."

为此,
REQ/REPhard-wiredtwo-step
[A.send()-[B].recv()-[B].send()-[A.recv()-[A].send()-[B].recv()-... 不看好,越不安全的选择。

1 ) 始终设置 zmq.LINGER = 0 以避免僵尸和挂断(为此 +1)

2 ) 如果不需要保留所有[A]端数据传递,可享受zmq.IMMEDIATE只传递生活 [B]zmq.CONFLATE 只提供最多 "fresh" 的价值 [A ]-边做了.send()

3 ) 如果需要保留所有 [A] 端的数据传递,将不得不 re-factor 在 [=37 上发送的策略=][A]-边变得健壮到缺失[B]-边,从而避免盲目的只看好data-pumping变成Context()-实例控制,但相当昂贵且资源非常有限,或者仔细计划和 pre-allocate 应有的能力,以便能够真正在内部存储所有的它们,直到 [B]-未来某个不确定的地方出现(或不出现)或 [A]- 侧丢弃或阻止或异常将是不可避免的。

4 ) 永远不要指望 built-in 琐碎的(原始的)原型能够满足您的生产需求,它们作为一种 LEGO-building 块用于一些更智能的 problem-specific 分布式信号和消息传递基础设施,而不是解决所有属性的魔杖(在这些 primitive-tools 实现时主要是未知和未定义的),因此随着 school-book 示例进入设计之外,将会有更多的工程工作健壮的分布式系统。这可能是一种使用 { PUSH/PULL + PULL/PUSH | PAIR/PAIR | XREQ/XREP } 加上 heart-beating 看门狗和 re-discovery 远程代理的组合的方法。稍后可能会添加一些其他原型,用于 N+1 故障恢复或使用工作负载平衡器或 remote-console 或延迟驱动的性能提升 off-site remote-logging - 如果需要,所有这些都取决于地狱的许多细节超出初始 post 或几个 SLOC。

5 ) 总是处理异常,即使 "masters" 告诉你不需要那样做。为什么?在 中,任何问题都不再是 just-local 问题,因此未处理的异常,陷入某些代理的无声死亡将导致缺少此类代理(许多)其他人确实依赖并且可能很容易在没有任何 local-reason 对他们可见的情况下被阻止。

6 ) 在生产领域,需要付出更多的努力来保护任何智能基础设施免受 remote-failures 和 DoS-alike 事件的影响,这些事件会影响本地-Context() SPOF,所以确实如此 架构设计既非常有趣又要求很高的领域。