2011-07-15 12 views
8

मैं PUSH/PULL मोड में zeroMQ साथ python उपयोग करने के लिए, आकार के संदेशों 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 बिट, कोर डुओ मशीन 2 [जीबी] रैम के साथ उपयोग कर रहा हूं।

नोट: मैं ही उदाहरण की कोशिश की RabbitMQ का उपयोग कर और सब कुछ अच्छी तरह से काम करता है - कोई संदेश खो दिया है। मैं परेशान हूं क्योंकि मैं अक्सर zeroMQ की प्रशंसा सुनता हूं। यह क्यों विफल हुआ जहां RabbitMQ सफल हुआ?

उत्तर

14

समस्या यह है कि जब कार्यक्रम निकलता है, तो सॉकेट तुरंत बंद हो जाता है और कचरा 0 के प्रभावी लिंगर के साथ एकत्रित होता है (यानी यह किसी भी अनुत्तरित संदेश को दूर करता है)। यह बड़े संदेशों के लिए एक समस्या है क्योंकि सॉकेट को कचरा इकट्ठा करने के लिए उन्हें भेजने के लिए अधिक समय लगता है।

प्रोग्राम से बाहर निकलने से पहले sleep(0.1) डालकर आप इससे बच सकते हैं (सॉकेट और संदर्भ को कचरा होने में संदर्भित करने के लिए)।

socket.setsockopt(zmq.LINGER, -1) (जो डिफ़ॉल्ट है) इस समस्या से बचने चाहिए, लेकिन यह किसी कारण से नहीं है कि मेरे पास जांच करने का समय नहीं है।

+0

सीडब्ल्यूबी, धन्यवाद। यह काम करता है, लेकिन ऐसा प्रतीत होता है कि 'खरगोश एमक्यू' इतना अधिक विश्वसनीय है। मैं डेटा की 40-60 [एमबी] को आसानी से भेज सकता हूं, जबकि 'शून्य एमक्यू' चीजें अटक जाती हैं/विश्वसनीय रूप से काम नहीं करती हैं। – user3262424

+1

पर्याप्त मेला। मुझे नहीं पता कि इस मामले में 0 एमक्यू या पायज्मक को दोष देना है या नहीं; अंतिम परिणाम आपकी परवाह किए बिना परेशानी है। क्या RabbitMQ पर 0 एमक्यू लाभ के लायक हैं, यह निश्चित रूप से आपका निर्णय है।डेटा का 40-60 एमबी या तो 0 एमक्यू के लिए कोई समस्या नहीं होनी चाहिए; लेकिन यहां कुछ ऐसा कर रहा है ... – cwb

+0

मुझे पता है कि '0 एमक्यू' काम करना चाहिए (और शायद, 'खरगोश एमक्यू' से भी तेज काम करता है) - फिर भी, मेरे सीमित परीक्षण से, जब तक कि किसी को ** चरम गति ** की आवश्यकता न हो - 'rabbitMQ' अधिक विश्वसनीय है। – user3262424

1

यह कल्पना की जा सकती है कि आप स्मृति से बाहर हो रहे हैं (निर्भर करता है कि आप संदेश कैसे भेज रहे हैं, भले ही वे पर्याप्त तेज़ी से उपभोग कर रहे हों)। आप socket.setsockopt(zmq.HWM) का उपयोग HWM को एक सौ मूल्य पर सेट करने के लिए कर सकते हैं और ज़ीरोमक को आउटगोइंग बफर में बहुत से संदेशों को संग्रहीत करने से रोक सकते हैं। इसे ध्यान में रखते, थोड़ा संशोधित उदाहरण पर विचार करें: सर्वर से

for i in {1..10}; do 
    python client.py & 
done 

आप देख सकते हैं सभी संदेशों को प्राप्त कर रहे हैं:

# 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 परीक्षण ग्राहकों चल

Total messages recieved: 9998 
Total messages recieved: 9999 
Total messages recieved: 10000 
+1

zeekay, धन्यवाद। ऐसा प्रतीत होता है कि खरगोश एमक्यू इतनी अधिक विश्वसनीय है कि 'शून्य एमक्यू'। 320 [एमबी] भेजने के लिए मैं बस सफल हुआ (हालांकि इसमें कुछ समय लगा)। 'शून्य एमक्यू 'अटक गया/विश्वसनीय रूप से काम नहीं करता है। – user3262424

+1

अरे जो भी आपके लिए काम करता है। – zeekay

संबंधित मुद्दे