Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python ZeroMQ推/拉--消息丢失?_Python_Zeromq - Fatal编程技术网

Python ZeroMQ推/拉--消息丢失?

Python ZeroMQ推/拉--消息丢失?,python,zeromq,Python,Zeromq,我试图在PUSH/PULL模式下使用python和zeroMQ,每隔几秒钟发送大小4[MB]的消息 出于某种原因,虽然看起来所有消息都已发送,但服务器似乎只收到了其中一些消息。我错过了什么 下面是客户端的代码--client.py import zmq import struct # define a string of size 4[MB] msgToSend = struct.pack('i', 45) * 1000 * 1000 context = zmq.Context() so

我试图在
PUSH/PULL
模式下使用
python
zeroMQ
,每隔几秒钟发送大小4[MB]的消息

出于某种原因,虽然看起来所有消息都已发送,但服务器似乎只收到了其中一些消息。我错过了什么

下面是客户端的代码--
client.py

import zmq
import struct

# define a string of size 4[MB] 
msgToSend = struct.pack('i', 45) * 1000 * 1000 

context = zmq.Context()
socket = context.socket(zmq.PUSH)
socket.connect("tcp://127.0.0.1:5000")

# print the message size in bytes
print len(msgToSend)

socket.send(msgToSend)

print "Sent message"
import zmq
import struct

context = zmq.Context()
socket = context.socket(zmq.PULL)
socket.bind("tcp://127.0.0.1:5000")

while True:
    # receive the message
    msg = socket.recv()

    print "Message Size is: {0} [MB]".format( len(msg) / (1000 * 1000) )
这是服务器的代码--
server.py

import zmq
import struct

# define a string of size 4[MB] 
msgToSend = struct.pack('i', 45) * 1000 * 1000 

context = zmq.Context()
socket = context.socket(zmq.PUSH)
socket.connect("tcp://127.0.0.1:5000")

# print the message size in bytes
print len(msgToSend)

socket.send(msgToSend)

print "Sent message"
import zmq
import struct

context = zmq.Context()
socket = context.socket(zmq.PULL)
socket.bind("tcp://127.0.0.1:5000")

while True:
    # receive the message
    msg = socket.recv()

    print "Message Size is: {0} [MB]".format( len(msg) / (1000 * 1000) )
我错过了什么?我如何保证邮件始终被发送且不会丢失

如果有必要,我使用的是
ubuntu10.04
32位的双核机器,内存为2[GB]


注意:我使用
RabbitMQ
尝试了相同的示例,一切都很好——没有消息丢失。我很困惑,因为我经常听到对
zeroMQ
的赞扬。为什么它在
RabbitMQ
成功的地方失败了

可以想象,您的内存正在耗尽(取决于您发送消息的方式,消息的消耗速度是否足够快等等)。您可以使用
socket.setsockopt(zmq.HWM)
HWM
设置为正常值,并防止zeromq在传出缓冲区中存储过多消息。考虑到这一点,考虑稍微修改的例子:

# server
...
counter = 0
while True:
    ...receive the message
    counter += 1
    print "Total messages recieved: {0}".format(counter)

# client
socket.setsockopt(zmq.HWM, 8)
for i in range(1000):
    socket.send(msgToSend)
然后运行10个测试客户端:

for i in {1..10}; do
    python client.py &
done
从服务器上可以看到接收到的所有消息:

Total messages recieved: 9998
Total messages recieved: 9999
Total messages recieved: 10000

问题是,当程序退出时,套接字会立即关闭,并以0的有效延迟进行垃圾回收(即,它会丢弃任何未发送的消息)。对于较大的消息来说,这是一个问题,因为它们发送的时间比套接字被垃圾收集的时间要长

您可以通过在程序退出之前放置
sleep(0.1)
来避免这种情况(延迟套接字和上下文被垃圾收集)


socket.setsockopt(zmq.LINGER,-1)
(默认设置)应该可以避免此问题,但由于某些原因,我没有时间调查此问题。

cwb,谢谢。它可以工作,但似乎
rabbitMQ
更可靠。我甚至可以流畅地发送40-60[MB]的数据,而在
zeroMQ
中,事情会卡住/无法可靠地工作。这很公平。在这种情况下,我不知道该怪0MQ还是pyzmq;不管怎样,最终结果都会给你带来麻烦。当然,与RabbitMQ相比,0MQ的好处是否值得,这是您的决定。40-60MB的数据对于0MQ来说也不成问题;但是这里有一些东西正在跳动…我知道 0MQ应该工作(也许比<代码> RabByMQ)更快——但是,从我有限的测试来看,除非需要极端的速度--<代码> RabByMQ 更可靠。这个Python问题似乎也适用于C++。我有同样的问题,两个线程写入同一个目标(tcp://host:port),每个线程都在快速创建和销毁套接字。看起来,当一个线程销毁其套接字时,它的副作用是销毁来自另一个套接字的未发送消息(即使“套接字”是线程本地的)。rabbitMQ似乎更具相关性,以至于
zeroMQ
。我刚刚成功(虽然需要一些时间)发送了320[MB]<代码>zeroMQ卡住/工作不可靠。