8

サイズ4[MB]のメッセージを数秒ごとに送信pythonするモードで使用しようとしてzeroMQいます。PUSH / PULL

何らかの理由で、すべてのメッセージが送信されたように見えますが、サーバーによって受信されたのは一部のメッセージのみであるように見えます。ここで何が欠けていますか?

これがクライアントのコードです-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、2[GB]RAMを搭載した32ビットのCoreDuoマシンを使用しています。

注:同じ例を使用して試しましたがRabbitMQ、すべてが正常に機能します。メッセージが失われることはありません。の称賛をよく聞くので困惑しzeroMQます。RabbitMQ成功したところで失敗したのはなぜですか?

4

2 に答える 2

14

問題は、プログラムが終了すると、ソケットがすぐに閉じられ、有効なLINGERが0のガベージコレクションが行われることです(つまり、未送信のメッセージがすべて破棄されます)。これは、ソケットがガベージコレクションされるよりも送信に時間がかかるため、大きなメッセージの場合に問題になります。

これを回避するsleep(0.1)には、プログラムが終了する直前に配置します(ソケットとコンテキストがガベージコレクションされるのを遅らせるため)。

socket.setsockopt(zmq.LINGER, -1)(これがデフォルトです)この問題を回避する必要がありますが、何らかの理由で調査する時間がなかったわけではありません。

于 2011-07-15T07:59:51.510 に答える
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
于 2011-07-15T04:42:53.163 に答える