我尝试在python
模式下使用zeroMQ
PUSH / PULL
,每隔几秒发送一次 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"
以下是服务器的代码 - server.py
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) )
我错过了什么?如何保证邮件始终发送而不丢失?
如果重要,我使用的是Ubuntu 10.04
32位Core Core机器,内存为2 [GB]。
注意:我使用RabbitMQ
尝试相同的示例,一切正常 - 没有消息丢失。因为我经常听到zeroMQ
的赞美,我感到很困惑。为什么在RabbitMQ
成功的地方失败了?
答案 0 :(得分:14)
问题是当程序退出时,套接字立即关闭,垃圾收集的有效LINGER为0(即它抛出任何未发送的消息)。对于较大的消息,这是一个问题,因为它们需要更长的时间来发送,而不是对套接字进行垃圾回收。
您可以通过在程序退出之前放置sleep(0.1)
来避免这种情况(延迟套接字和上下文被垃圾回收)。
socket.setsockopt(zmq.LINGER, -1)
(这是默认设置)应避免此问题,但由于某些原因我没有时间进行调查。
答案 1 :(得分:1)
可以想象你的内存不足(取决于你如何发送消息,是否消耗得足够快等等)。您可以使用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