2008-09-17 8 views
17

के लिए एमएसएमक्यू बाइंडिंग में संदेश विफलता को कैसे संभाल सकता हूं मैंने एक डब्ल्यूसीएफ सेवा बनाई है और नेटमैस्क्विंड बाइंडिंग का उपयोग कर रहा हूं।मैं डब्ल्यूसीएफ

यह एक साधारण सेवा है जो मेरी सेवा विधि में डीटीओ पास करती है और प्रतिक्रिया की अपेक्षा नहीं करती है। संदेश एक एमएसएमक्यू में रखा गया है, और एक बार डेटाबेस में डाला गया।

यह सुनिश्चित करने के लिए सबसे अच्छी विधि क्या है कि कोई डेटा खो नहीं जा रहा है।

2 निम्न विधियों की कोशिश की है:

  1. यह मैनुअल अवलोकन के लिए एक मृत पत्र कतार में संदेश देता है एक अपवाद

    फेंक। मैं इस पर कार्रवाई कर सकते हैं जब मेरे strvice शुरू होता है

  2. सेट receiveRetryCount = "3" बाध्यकारी

    3 के बाद के प्रयासों में वे - जो instantanously हो, इस कतार में संदेश छोड़, लेकिन मेरी सेवा दोष लगता है। मेरी सेवा को पुनरारंभ करना इस प्रक्रिया को दोहराता है। इसके विफल होने पर

    कोशिश प्रक्रिया संदेश

    • , उस संदेश के लिए 5 मिनट तक प्रतीक्षा करें और दोबारा कोशिश:

आदर्श रूप में मैं पालन करना चाहते हैं।

  • यदि यह प्रक्रिया 3 बार विफल हो जाती है, तो संदेश को मृत पत्र कतार में ले जाएं।
  • सेवा को पुनरारंभ करने से सभी संदेशों को मृत अक्षर कतार से वापस कतार में धक्का दिया जाएगा ताकि इसे संसाधित किया जा सके।
  • क्या मैं इसे प्राप्त कर सकता हूं? यदि हां, तो कैसे? क्या आप मुझे दिए गए स्केनेरिया के लिए डब्ल्यूसीएफ और एमएसएमक्यू का सर्वोत्तम उपयोग करने के तरीके पर किसी भी अच्छे लेख के बारे में बता सकते हैं।

    किसी भी मदद की बहुत सराहना की जाएगी। धन्यवाद!

    कुछ अतिरिक्त जानकारी के

    मैं Windows XP और Windows Server 2003 पर MSMQ 3.0 का उपयोग कर रहा दुर्भाग्य से मैं जहर संदेश समर्थन MSMQ 4.0 और Vista/2008 पर लक्षित में बनाया का उपयोग नहीं कर सकते हैं।

    उत्तर

    9

    एसडीके में एक नमूना है जो आपके मामले में उपयोगी हो सकता है। असल में, यह आपके सेवा में एक आईररहैंडलर कार्यान्वयन को संलग्न करता है जो त्रुटि को पकड़ लेगा जब डब्ल्यूसीएफ संदेश को "जहर" घोषित करता है (यानी जब सभी कॉन्फ़िगर किए गए रीट्रीज़ समाप्त हो जाते हैं)। नमूना क्या करता है संदेश को दूसरी कतार में ले जाता है और फिर संदेश से जुड़े सर्विसहोस्ट को पुनरारंभ करता है (क्योंकि जहर संदेश मिलने पर यह गलती होगी)।

    यह एक बहुत ही सुंदर नमूना नहीं है, लेकिन यह उपयोगी हो सकता है। कुछ सीमाएं हैं, हालांकि:

    1- यदि आपके पास आपकी सेवा से जुड़ी कई अंतराल हैं (यानी कई कतारों के माध्यम से उजागर), तो यह जानने का कोई तरीका नहीं है कि जहर संदेश किस कतार में आया था। अगर आपके पास केवल एक क्यूई है एकल कतार, यह एक समस्या नहीं होगी।मैंने इसके लिए कोई आधिकारिक कामकाज नहीं देखा है, लेकिन मैंने एक संभावित विकल्प के साथ प्रयोग किया है जिसे मैंने यहां दस्तावेज किया है: http://winterdom.com/weblog/2008/05/27/NetMSMQAndPoisonMessages.aspx

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

    ईमानदार होने के लिए, किसी भी मामले में, आप यहां कुछ "मैन्युअल" काम देख रहे हैं जो डब्ल्यूसीएफ सिर्फ अपने आप को कवर नहीं करता है।

    मैं हाल ही में एक अलग परियोजना पर काम कर रहा हूं जहां मुझे स्पष्ट रूप से नियंत्रित करने की आवश्यकता है कि कितनी बार रिट्री होती है, और मेरा वर्तमान समाधान पुनः प्रयास कतारों का एक सेट बनाना था और मैन्युअल रूप से पुनः प्रयास कतारों और मुख्य के बीच संदेशों को स्थानांतरित करना था टाइम्स और कुछ हेरिस्टिक्स के सेट पर आधारित प्रसंस्करण कतार, केवल कच्चे सिस्टम का उपयोग करना। एमएसएमक्यू कतारों को संभालने के लिए मैसेजिंग सामान। ऐसा लगता है कि अगर आप इस तरह से जाते हैं तो कुछ मिलते हैं।

    14

    मैं MSMQ (केवल Vista पर तो उपलब्ध) के साथ लगता है कि आप इस तरह करने के लिए कर सकता है:

    <bindings> 
        <netMsmqBinding> 
         <binding name="PosionMessageHandling" 
          receiveRetryCount="3" 
          retryCycleDelay="00:05:00" 
          maxRetryCycles="3" 
          receiveErrorHandling="Move" /> 
        </netMsmqBinding> 
    </bindings> 
    

    WCF तुरंत पहली कॉल की विफलता के बाद ReceiveRetryCount समय के लिए फिर से प्रयास करेगा। बैच विफल होने के बाद संदेश को रीट्री कतार में स्थानांतरित कर दिया गया है। RetryCycleDelay मिनट की देरी के बाद, संदेश पुनः प्रयास कतार से एंडपॉइंट कतार में स्थानांतरित हो गया और बैच को पुनः प्रयास किया गया। यह मैक्सरीट्रीकल समय दोहराया जाएगा।यदि सब उस संदेश में विफल रहता है receiveErrorHandling के अनुसार नियंत्रित किया जाता है (जहर कतार में) ले जाते हैं, अस्वीकार, ड्रॉप या गलती

    वैसे WCF के बारे में एक अच्छा पाठ किया जा सकता है और MSMQ से Progammig WCF पुस्तक के chapther 9 जो जुवाल लोवी

    +0

    यह एमएसएमक्यू 4.0 पर लागू होता है एमएसएमक्यू 3.0 – Perhentian

    1

    दुर्भाग्यवश मैं विंडोज एक्सपी और विंडोज सर्वर 2003 पर फंस गया हूं, इसलिए यह मेरे लिए एक विकल्प नहीं है। - (मैं फिर से स्पष्टीकरण दूंगा कि पोस्टिंग के बाद मुझे यह समाधान मिला और मुझे एहसास हुआ कि मैं इसका उपयोग नहीं कर सका)

    मैंने पाया कि एक समाधान एक कस्टम हैंडलर स्थापित करना था जो मेरे संदेश को दूसरी कतार में ले जाएगा या जहर कतार और मेरी सेवा को पुनरारंभ करें। यह मेरे लिए पागल लग रहा था। कल्पना करें कि मेरा एसक्यूएल सर्वर नीचे था कि सेवा कितनी बार पुनरारंभ की जाएगी।

    तो मैंने जो किया है, वह लाइन को गलती करने और कतार पर संदेश छोड़ने की अनुमति दे रहा है। मैं अपने सिस्टम लॉगिंग सेवा के लिए एक घातक संदेश भी लॉग करता हूं जो यह हुआ है। एक बार हमारी समस्या हल हो जाने के बाद, मैं सेवा को पुनरारंभ करता हूं और सभी संदेशों को फिर से संसाधित करना शुरू हो जाता है।

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

    aogan, आप MSMQ 4.0 के लिए एकदम सही जवाब था, लेकिन दुर्भाग्य से नहीं करने के लिए मुझे

    4

    आप एसक्यूएल-सर्वर का उपयोग कर रहे हैं तो आप दोनों MSMQ और SQL-सर्वर यह समर्थन के बाद से, एक वितरित लेन-देन का उपयोग करना चाहिए। क्या होता है क्या आप अपने डेटाबेस को एक लेनदेनस्कोप ब्लॉक में लिखते हैं और स्कोप कॉल करते हैं। पूर्ण() केवल तभी सफल होता है जब यह सफल होता है। यदि यह विफल हो जाता है, तो जब आपकी डब्लूसीएफ विधि वापस आती है तो संदेश को फिर से प्रयास करने के लिए कतार में रखा जाएगा। यहाँ है कोड का एक छंटनी संस्करण मैं का उपयोग करें: - 16 संदेशों

    [OperationBehavior(TransactionScopeRequired=true, TransactionAutoComplete=true)] 
        public void InsertRecord(RecordType record) 
        { 
         try 
         { 
          using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required)) 
          { 
           SqlConnection InsertConnection = new SqlConnection(ConnectionString); 
           InsertConnection.Open(); 
    
           // Insert statements go here 
    
           InsertConnection.Close(); 
    
           // Vote to commit the transaction if there were no failures 
           scope.Complete(); 
          } 
         } 
         catch (Exception ex) 
         { 
          logger.WarnException(string.Format("Distributed transaction failure for {0}", 
           Transaction.Current.TransactionInformation.DistributedIdentifier.ToString()), 
           ex); 
         } 
        } 
    

    मैं रिकॉर्ड की एक बड़ी लेकिन ज्ञात संख्या को कतार करके इसकी जांच, WCF धागे एक साथ उनमें से कई को संभालने के लिए बहुत सारी शुरू करते हैं (16 धागे तक पहुँच जाता है एक बार में कतार से बाहर), फिर संचालन के बीच में प्रक्रिया को मार डालो। जब प्रोग्राम को पुनरारंभ किया जाता है तो संदेश कतार से वापस पढ़े जाते हैं और फिर से संसाधित होते हैं जैसे कि कुछ नहीं हुआ, और परीक्षण के समापन पर डेटाबेस सुसंगत है और इसमें कोई अनुपलब्ध रिकॉर्ड नहीं है।

    वितरित लेनदेन प्रबंधक की परिवेश उपस्थिति है, और जब आप लेनदेनस्कोप का एक नया उदाहरण बनाते हैं तो यह स्वचालित रूप से विधि आवंटन के दायरे में वर्तमान लेनदेन की खोज करता है - जो इसे पहले से डब्लूसीएफ द्वारा बनाया गया था कतार से संदेश और अपनी विधि का आह्वान किया।

    +0

    हाय क्रिस। मुझे यकीन है कि आपके ऑपरेशन व्यवहार को TransactionScopeRequired = true को श्रेय देना आपके एसक्यूएल कॉल को लेनदेन स्कोप में लपेटने की आवश्यकता को अस्वीकार करता है क्योंकि यह पहले से ही किया जा रहा है। कहा जा रहा है, मुझे यकीन नहीं है कि आपका उत्तर एमएसएमक्यू के मेरे प्रश्न से कैसे संबंधित है। – WebDude