2009-11-25 13 views
12

कुछ समय पहले मेरा मूल प्रश्न MSMQ Slow Queue Reading है, हालांकि मैंने उस से उन्नत किया है और अब मुझे लगता है कि मैं समस्या को और अधिक स्पष्ट समझता हूं।एमएसएमक्यू प्राप्त करें() विधि टाइमआउट

मेरे कोड (अच्छी तरह से वास्तव में मैं उपयोग कर रहा हूँ एक खुला स्रोत पुस्तकालय का हिस्सा) इस तरह दिखता है:

queue.Receive(TimeSpan.FromSeconds(10), MessageQueueTransactionType.Automatic); 

कौन सा Messaging.MessageQueue.Receive समारोह का उपयोग कर और कतार है एक MessageQueue है। समस्या इस प्रकार है।

कोड की उपरोक्त पंक्ति निर्दिष्ट टाइमआउट (10 सेकंड) के साथ कॉल की जाएगी। Receive(...) फ़ंक्शन एक अवरुद्ध फ़ंक्शन है, और तब तक ब्लॉक करना चाहिए जब तक कि कतार में कोई संदेश न आए, उस समय यह वापस आएगा। यदि टाइमआउट हिट होने से पहले कोई संदेश प्राप्त नहीं होता है, तो यह समय-समय पर वापस आ जाएगा। यदि फ़ंक्शन कहलाता है तो कतार में कोई संदेश होता है, तो वह तुरंत उस संदेश को वापस कर देगा।

हालांकि, क्या हो रहा है Receive(...) फ़ंक्शन कहा जा रहा है, यह देखते हुए कि कतार में कोई संदेश नहीं है, और इसलिए एक नया संदेश आने का इंतजार है। जब कोई नया संदेश आता है (टाइमआउट से पहले), यह इस नए संदेश का पता नहीं लगा रहा है और इंतजार कर रहा है। अंततः टाइमआउट मारा जाता है, जिस बिंदु पर कोड जारी रहता है और Receive(...) को फिर से कॉल करता है, जहां यह संदेश उठाता है और इसे संसाधित करता है।

अब, यह समस्या केवल कई दिनों/सप्ताह के बाद होती है। मैं & कतार को पुनर्जीवित करके इसे सामान्य रूप से फिर से काम कर सकता हूं। यह विभिन्न कंप्यूटरों, और विभिन्न कतारों पर होता है। तो ऐसा लगता है कि कुछ ऐसा हो रहा है, जब तक कि Receive(...) फ़ंक्शन का उपयोग करने वाली ट्रिगरिंग/अधिसूचना क्षमता को तोड़ने पर कुछ बिंदु न हो।

मैंने कई अलग-अलग चीजों की जांच की है, और सब कुछ सामान्य लगता है & सामान्य रूप से काम कर रहे कतार से अलग नहीं है। बहुत सी डिस्क स्पेस (13 गीगा फ्री) और रैम है (मैं जो बता सकता हूं उससे 1 जीबी से लगभग 350 एमबी मुक्त)। मैंने रजिस्ट्री प्रविष्टियों की जांच की है जो सभी अन्य कतारों के समान दिखाई देते हैं, और प्रदर्शन मॉनीटर सामान्य से कुछ भी नहीं दिखाता है। मैंने टीएमक्यू उपकरण भी चलाया है और उसमें से कुछ भी गलत रूप से गलत नहीं देख सकता।

मैं सभी मशीनों पर विंडोज एक्सपी का उपयोग कर रहा हूं और उनके पास सर्विस पैक 3 स्थापित है। मैं कतारों में बड़ी संख्या में संदेश नहीं भेज रहा हूं, अधिकतर यह प्रत्येक 2 सेकंड में 1 होगा लेकिन आमतौर पर उससे बहुत कम बार-बार होता है। संदेश केवल छोटे हैं और कहीं भी 4 एमबी सीमा के पास नहीं हैं।

एकमात्र चीज जो मैंने अभी देखी है वह है p0000001.mq और r0000067.mq फ़ाइलें सी: \ विन्डोज़ \ system32 \ msmq \ स्टोरेज दोनों 4,096 केबी हैं, हालांकि वे अन्य कंप्यूटरों पर भी आकार हैं जो वर्तमान में अनुभव नहीं कर रहे हैं समस्या। समस्या कंप्यूटर पर प्रत्येक कतार में एक साथ नहीं होती है, क्योंकि मैं कंप्यूटर पर 1 समस्या कतार को फिर से बना सकता हूं और अन्य कतारों को अभी भी समस्या का अनुभव होता है।

मुझे एमएसएमक्यू के साथ बहुत अनुभवी नहीं है, इसलिए यदि आप संभव चीजों को जांचने के लिए पोस्ट करते हैं तो कृपया आप उन्हें कैसे जांच सकते हैं या कहां से बात कर रहे हैं, इस बारे में अधिक जानकारी प्राप्त कर सकते हैं।

वर्तमान स्थिति है:

  • computerâ - 4 कतारों सामान्य
  • ComputerB - 2 कतारों समस्या, 1 कतार सामान्य सामना
  • ComputerC - 2 कतारों समस्या
  • ComputerD का सामना - 1 कतार सामान्य
  • कंप्यूटरई - 2 कतार सामान्य

तो मेरे पास तुलना करने और परीक्षण करने के लिए बड़ी संख्या में कंप्यूटर/कतार हैं।

+0

क्या खुला स्रोत पुस्तकालय प्रयोग किया जाता है परीक्षण कर सकते हैं? क्या यह उनके पक्ष में एक ज्ञात मुद्दा है? –

+0

यह NServiceBus (www.nservicebus.com) है। ऐसा लगता है कि किसी और को इस मुद्दे का अनुभव नहीं होता है (कम से कम मेलिंग सूची पर कोई भी नहीं है)। यह कैसे काम करता है इसकी मेरी व्याख्या इस बात पर आधारित है कि मालिक इसका वर्णन कैसे करता है। "एक एनएस सर्विसबस थ्रेड पिछले संदेश (या स्टार्टअप पर) को संसाधित करने के बाद एक संदेश के लिए कतार को देखता है। एक संदेश के आने तक नियमित रूप से व्यवहार करना बंद होता है, लेकिन NServiceBus इसे समय-समय पर सीमित करता है ताकि सुंदर शट डाउन किसी भी समय पर "। और चिपकाए गए कोड की रेखा का उल्लेख 'peek' है। – mike

+1

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

उत्तर

0

इस

सार्वजनिक संदेश प्राप्त होता है (TimeSpan टाइमआउट, कर्सर कर्सर)

अतिभारित समारोह की कोशिश करो।

किसी संदेश क्यू के लिए कर्सर प्राप्त करने के लिए, उस कतार के लिए CreateCursor विधि को कॉल करें।

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

लेनदेन के भीतर संदेशों को पढ़ते समय, संदेश कतार में कर्सर आंदोलन वापस नहीं लेता है यदि लेनदेन निरस्त हो जाता है। उदाहरण के लिए, मान लें कि दो संदेश, ए 1 और ए 2 के साथ एक कतार है। यदि आप लेन-देन में संदेश ए 1 को हटाते हैं, तो संदेश कतार में कर्सर को संदेश A2 पर ले जाता है। हालांकि, यदि किसी भी कारण से लेनदेन निरस्त कर दिया गया है, तो संदेश ए 1 को कतार में वापस डाला गया है लेकिन कर्सर संदेश ए 2 पर इंगित करता है।

कर्सर को बंद करने के लिए, बंद करें पर कॉल करें।

8

कोई विशेष कारण है कि आप कतार सुनने के लिए किसी ईवेंट हैंडलर का उपयोग नहीं कर रहे हैं? सिस्टम। मैसेजिंग लाइब्रेरी आपको एक हैंडलर को कतार में जोड़ने की इजाजत देता है, अगर मैं समझता हूं कि आप सही तरीके से क्या कर रहे हैं, तो लूपिंग हर 10 सेकंड प्राप्त करें। इस तरह कुछ कोशिश करें:

class MSMQListener 
{ 
    public void StartListening(string queuePath) 
    { 
     MessageQueue msQueue = new MessageQueue(queuePath); 
     msQueue.ReceiveCompleted += QueueMessageReceived; 
     msQueue.BeginReceive(); 
    } 

    private void QueueMessageReceived(object source, ReceiveCompletedEventArgs args) 
    { 
     MessageQueue msQueue = (MessageQueue)source; 

     //once a message is received, stop receiving 
     Message msMessage = null; 
     msMessage = msQueue.EndReceive(args.AsyncResult); 

     //do something with the message 

     //begin receiving again 
     msQueue.BeginReceive(); 
    } 
} 
+0

मुख्य कारण यह है कि आप एक लेनदेन कतार से असीमित रूप से प्राप्त नहीं कर सकते हैं। इस प्रतिबंध को [मूल एपीआई] (https://msdn.microsoft.com/en-us/library/ms699825 (v = vs.85) .aspx तक नीचे जा सकता है)। – acelent

3

हम NServiceBus का भी उपयोग कर रहे हैं और हमारे नेटवर्क के अंदर एक ही समस्या थी।

असल में एमएसएमक्यू दो चरणों के साथ यूडीपी का उपयोग कर रहा है। एक संदेश प्राप्त होने के बाद इसे स्वीकार किया जाना चाहिए। जब तक इसे स्वीकार नहीं किया जाता है तब तक इसे ग्राहक पक्ष पर प्राप्त नहीं किया जा सकता है क्योंकि प्राप्त लेनदेन को अंतिम रूप दिया नहीं गया है।

यह हमारे लिए अलग अलग समय में अलग अलग बातें की वजह से किया गया था: - इस वितरित विनिमय कोऑर्डिनेटर फ़ायरवॉल गलत कॉन्फ़िगरेशन के रूप में मशीनों के बीच संवाद करने में असमर्थ होने के कारण था एक बार - एक और बार हम क्लोन आभासी मशीनों का उपयोग कर रहे थे sysprep बिना जो आंतरिक बनाया एमएसएमक्यू आईडी गैर-अनूठी है और इसे एक मशीन और एक दूसरे को एक संदेश मिला है। आखिर में एमएसएमक्यू चीजों को समझता है लेकिन इसमें काफी समय लगता है।

उम्मीद है कि इससे मदद मिलती है।

0

आप पूरी तरह से तुल्यकालिक और घटना के बिना कुछ उपयोग करना चाहते हैं यदि आप इस विधि

public object Receive(string path, int millisecondsTimeout) 
{ 
    var mq = new System.Messaging.MessageQueue(path); 
    var asyncResult = mq.BeginReceive(); 
    var handles = new System.Threading.WaitHandle[] { asyncResult.AsyncWaitHandle }; 
    var index = System.Threading.WaitHandle.WaitAny(handles, millisecondsTimeout); 
    if (index == 258) // Timeout 
    { 
     mq.Close(); 
     return null; 
    } 
    var result = mq.EndReceive(asyncResult); 
    return result; 
} 
संबंधित मुद्दे