如果没有收到回复,ZeroMQ'重新启动'

时间:2018-03-21 22:16:55

标签: python zeromq

我有一个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

2 个答案:

答案 0 :(得分:1)

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

  

&#34; [agent-A] 从我的客户端向我的服务器程序发送高度数据。我的服务器程序 [agent-B] 将不会一直运行所以如果我没有收到回复,我希望它 [agent-A] 再试一次。&#34;

为此,
REQ/REP 硬连线的两步 [<强> A ]发送() - 。[B] .recv() - [B]。发送() - [的 A ]的recv() - [的 A ]发送() - 。[B] .recv()-... 不是有希望的,不是一个安全的选择。

1)始终设置 zmq.LINGER = 0 以避免僵尸&amp;挂断(+1表示)

2)如果不需要保留所有 [A] 侧数据,可以享受 zmq.IMMEDIATE 仅提供给 [B] zmq.CONFLATE 只提供最多&#34;新鲜&#34;值 [A] -side做了.send()

3)如果需要保持所有 [A] 侧数据的传递,则必须重新考虑发送策略 [A] 对于缺少 [B] - 侧面变得强大,以避免盲目和乐观的数据泵入Context() - 实例控制,但相当昂贵和非常有限的资源,或仔细计划和预先分配适当的容量,以便能够确实在内部存储所有的&em,直到 [B] - 成为(或不)未来不确定的地方或者 [A] - 丢弃或阻止或异常将是不可避免的。

4)永远不要指望内置的琐碎(原始)原型能够满足您的生产需求,这些原型作为一种乐高构建模块,用于一些更智能,特定于问题的分布式信令和消息传递基础设施,而不是魔术棒为了解决所有属性(在这些原始工具实现时主要是未知的和未定义的),因此需要进行更多的工程工作,因为人们在学校书籍示例之外转向设计健壮的分布式系统。这可能是一种使用{ PUSH/PULL + PULL/PUSH | PAIR/PAIR | XREQ/XREP }的组合以及心跳监视器和重新发现远程代理的方法。其他一些原型可能会随后添加N + 1故障恢复或性能提升与工作负载平衡器或远程控制台或延迟激励的异地远程日志记录 - 如果需要,所有这些都取决于地狱之外的许多细节超出了最初的帖子或者很少有SLOC。

5)总是处理异常,即使&#34;主人&#34;告诉你一个人不必这样做。为什么?在中,任何问题都不再是一个公正的本地问题,所以未经处理的例外情况会陷入某些代理人的沉默死亡,这会导致全球影响,因为缺少这样的代理人(很多)其他人确实依赖并可能很容易被阻止没有任何本地原因可见

6)在生产领域,需要做出更多努力来保护任何智能基础设施免受远程故障和类似DoS的事件影响本地 - Context() SPOF,所以确实架构设计既非常有趣又非常苛刻。

答案 1 :(得分:0)

检查this,你会发现:

  

套接字zmq.REQ将阻止发送,除非它已成功收到回复。

这意味着在收到答案之前您无法发送其他请求。 ZMQ具有与您使用客户端/服务器zmq.REQ / zmq.REP不同的消息传递模式。

  

在未收到回复/请求的情况下,任何尝试向套接字(zmq.REQ / zmq.REP)发送另一条消息都将导致错误:

....
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