我正在编写一个用 ZeroMQ
在python中编写的无代理,平衡,客户端工作服务。
客户端获取工作人员的地址,建立连接(zmq.REQ / zmq.REP
),发送单个请求,接收单个响应然后断开连接。
我选择了无代理架构,因为需要在客户端和工作者之间传输的数据量相对较大,尽管每个连接只有一个REQ/REP
对,并且使用代理作为一个中间人'会造成瓶颈。
在测试系统时,我注意到客户端和工作人员之间的通信是随机停止的,有时仅在几秒钟后恢复(通常是几分钟)。
我将问题范围缩小到.connect()
/ .disconnect()
客户工作人员。
我写了两个小的python脚本来重现这个bug。
import zmq
class Site:
def __init__(self):
ctx = zmq.Context()
self.pair_socket = ctx.socket(zmq.REQ)
self.num = 0
def __del__(self):
print "closed"
def run_site(self):
print "running..."
while True:
self.pair_socket.connect('tcp://127.0.0.1:5555')
print 'connected'
self.pair_socket.send_pyobj(self.num)
print 'sent', self.num
print self.pair_socket.recv_pyobj()
self.pair_socket.disconnect('tcp://127.0.0.1:5555')
print 'disconnected'
self.num += 1
s = Site()
s.run_site()
和
import zmq
class Server:
def __init__(self):
ctx = zmq.Context()
self.pair_socket = ctx.socket(zmq.REP)
self.pair_socket.bind('tcp://127.0.0.1:5555')
def __del__(self):
print " closed"
def run_server(self):
print "running..."
while True:
x = self.pair_socket.recv_pyobj()
print x
self.pair_socket.send_pyobj(x)
s = Server()
s.run_server()
我认为这个问题与记忆或 gc
无关,因为我尝试过停用gc
- 没有多大影响。
我尝试使用 zmq.LINGER
,如下所述:Zeromq with python hangs if connecting to invalid socket
什么可能导致这些rand冻结?
答案 0 :(得分:0)
根据定义,REP
套接字是同步的。因此,您的服务器一次只能处理一个请求,其余的只会填满缓冲区并在某些时候丢失。
要解决根本原因,您需要使用ROUTER
套接字。
class Server:
def __init__(self):
ctx = zmq.Context()
self.pair_socket = ctx.socket(zmq.ROUTER)
self.pair_socket.bind('tcp://127.0.0.1:5555')
self.poller = zmq.Poller()
self.poller.register(self.pair_socket, zmq.POLLIN)
def __del__(self):
print " closed"
def run_server(self):
print "running..."
while True:
try:
items = dict(self.poller.poll())
except KeyboardInterrupt:
break
if self.pair_socket in items:
x = self.pair_socket.recv_multipart()
print x
self.pair_socket.send_multipart(x)