ZeroMQ:即使在设置HWM和bufsize之后,数据包也会丢失

时间:2017-05-03 23:56:52

标签: zeromq distributed-computing

我们在ZeroMQ中使用PUSH/PULL可扩展的形式通信模式。发件人应用程序总共发送30,000条消息,每条消息10kB。有很多数据丢失,因此我们在发件人方面设置了以下内容:

zmq_socket = context.socket(zmq.PUSH)
zmq_socket.setsockopt(zmq.SNDBUF, 10240)
zmq_socket.setsockopt(zmq.SNDHWM, 1)
zmq_socket.bind("tcp://127.0.0.1:4999")

在接收方:

zmq_socket = context.socket(zmq.PULL)
zmqSocket.setReceiveBufferSize(10240);
zmqSocket.setRcvHWM(1);
zmq_socket.connect("tcp://127.0.0.1:4999")

仍有数据丢失。不确定我们如何避免数据包被静默删除。

编辑1:
Python中的发件人代码:

context = zmq.Context()
zmq_socket = context.socket(zmq.PUSH)
zmq_socket.setsockopt(zmq.SNDBUF, 10240)
zmq_socket.setsockopt(zmq.SNDHWM, 1)
zmq_socket.bind("tcp://127.0.0.1:4999")

for file_name in list_of_files:              # Reads data from a list of files:
    while True:                              #       data from a file_name
          with open(os.path.join(self.local_base_dir,file_name), 'r') as sf:
               socket_data = sf.read(5120)
               if socket_data == '':
                  sf.close()
                  break                      #       until EoF

               ret = zmq_socket.send(socket_data)

               if ret == 0:
                  return True

               if ret == -1:
                  print zmq_errno()
Java中的

Receiver 代码:

    private ZMQ.Socket zmqSocket = zmqContext.socket(ZMQ.PULL);       
    zmqSocket.setReceiveBufferSize(10240);
    zmqSocket.setRcvHWM(1);
    zmqSocket.connect(socketEndpoint);
    String message = new String(zmqSocket.recv());
    messages.add(message);

1 个答案:

答案 0 :(得分:0)

使用ZMQ_IMMEDIATE标志可以防止排队到没有完成连接的管道的消息丢失。

来自http://api.zeromq.org/4-2:zmq-setsockopt#toc21

  

ZMQ_IMMEDIATE:仅将消息排入已完成的连接

     

默认情况下,队列将填充传出连接,即使是   连接尚未完成。这可能会导致“丢失”的消息   带有循环路由的套接字(REQPUSHDEALER)。如果这个选项   如果设置为1,则消息应仅排队到已完成的连接。   如果没有其他连接,这将导致套接字阻塞,   但会阻止队列填充等待连接的管道。   选项值类型int选项值unit boolean默认值0   (false)适用的套接字类型全部,仅用于面向连接   传输。

zmq_socket.setsockopt(zmq.ZMQ_IMMEDIATE, 1)