2013-01-03 36 views
11

एक आरईएसटी सेवा के सामने एक अनुरोध कतार रखने के लिए सबसे अच्छा प्रौद्योगिकी समाधान (ढांचा/दृष्टिकोण) क्या है। ताकि मैं उच्च उपलब्धता के लिए आरईएसटी सेवा के उदाहरणों को बढ़ा सकूं और सेवा क्लाइंट के लिए सेवा/लेनदेन सीमा बनाने के लिए अनुरोध कतार को सामने रख सकूं।एक आरईएसटी सेवा के सामने अनुरोध कतार

  1. मैं अनुरोध क़तार (जावा) इसके साथ एक प्रतिस्पर्धा उपभोक्ता को लागू करने के
  2. दृष्टिकोण के लिए अच्छा है और हल्के प्रौद्योगिकी/ढांचे विकल्प की जरूरत है।
+3

आप एक लोड संतुलन का उपयोग कर सकते हैं? – Henry

+0

आपने अभी तक क्या पाया है? – miku

+2

@ हेनरी वह हो सकता है जो वह चाहता है कि पूल के अनुरोधों की कतार रखे, भले ही सभी एप्सर्स व्यस्त हैं, कोई अनुरोध अस्वीकार नहीं किया जाना चाहिए, इंटीड वे पूल में अपनी बारी के लिए इंतजार कर रहे हैं। – Subin

उत्तर

7

आपके लक्ष्यों के आधार पर यहां कुछ समस्याएं हैं।

सबसे पहले, यह केवल बैक एंड पर संसाधनों की उपलब्धता को बढ़ावा देता है। इस बात पर विचार करें कि क्या आपके पास बैक एंड पर कतार अनुरोधों को संभालने वाले 5 सर्वर हैं। यदि उनमें से एक सर्वर नीचे चला जाता है, तो कतारबद्ध अनुरोध कतार में वापस आना चाहिए, और शेष 4 सर्वरों में से एक को फिर से वितरित किया जाना चाहिए।

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

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

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

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

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

इस हाथ को प्रकट करने के लिए, आपको सर्विसलेट 3.0 को संभालने वाले असिंक्रोनस सर्वलेट पर एक नज़र डालना चाहिए, और नवीनतम जेटी (निश्चित संस्करण नहीं है), ग्लासफ़िश 3.x, और अन्य में टॉमकैट 7 में उपलब्ध है।

इस मामले में जब आप अनुरोध करेंगे तो आप क्या करेंगे, आप नाममात्र सिंक्रोनस सर्वलेट कॉल को HttpServletRequest.startAsync(HttpServletRequest request, HttpServletResponse response) का उपयोग करके असीमित कॉल में कनवर्ट करें।

यह एक असिंक्रोनस कॉन्टेक्स्ट लौटाता है, और एक बार शुरू होने पर, सर्वर को प्रोसेसिंग थ्रेड को मुक्त करने की अनुमति देता है। फिर आप कई चीजें करते हैं।

  1. अनुरोध से पैरामीटर निकालें।
  2. अनुरोध के लिए एक अद्वितीय आईडी बनाएं।
  3. अपने पैरामीटर से एक नया बैक एंड अनुरोध पेलोड बनाएं।
  4. AsyncContext के साथ आईडी को संबद्ध करें, और संदर्भ को बनाए रखें (जैसे इसे एक विस्तृत विस्तृत मानचित्र में डालना)।
  5. जेएमएस कतार में बैक एंड अनुरोध सबमिट करें।

इस बिंदु पर, प्रारंभिक प्रसंस्करण किया जाता है, और आप बस डॉगेट (या सेवा, या जो कुछ भी) से वापस आते हैं। चूंकि आपने AsyncContext.complete() को नहीं कहा है, सर्वर सर्वर से कनेक्शन बंद नहीं करेगा। चूंकि आपके पास आईडी द्वारा मानचित्र में AsyncContext स्टोर है, इसलिए यह समय के लिए सुरक्षित रखने के लिए आसान है।

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

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

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

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

यह आंतरिक कतार एक थ्रेड पूल द्वारा समर्थित है जिसका काम अनुरोध पेलोड को मूल कनेक्शन पर वापस भेजना है। यह संदेश से मूल अनुरोध आईडी निकालने से पहले, उस आंतरिक मानचित्र से AsyncContext को देखकर, और फिर परिणाम को AsyncContext से जुड़े HttpServletResponse पर भेजकर करता है। अंत में, यह आपके द्वारा किए गए सर्वर को बताने और कनेक्शन को रिलीज़ करने की अनुमति देने के लिए AsyncContext.complete() (या एक समान विधि) को कॉल करता है।

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

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

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

आप इन अनुरोधों का पुन: उपयोग नहीं कर सकते हैं, वास्तव में ऐसी चीज नहीं है जैसे लोड बैलेंसर क्लाइंट पर वापस जा रहा है। यदि ग्राहक आपको प्रकाशित अंत बिंदुओं के माध्यम से कॉलबैक करने की इजाजत दे रहा है, तो सुनिश्चित करें कि आप केवल एक और जेएमएस संदेश हैंडलर उन अनुरोधों को कर सकते हैं। लेकिन यह एक वास्तविक प्रकार की बात नहीं है, चर्चा के इस स्तर पर आरईएसटी अधिक ग्राहक/सर्वर/आरपीसी है।

किस ढांचे के रूप में कच्चे सर्वलेट की तुलना में उच्च स्तर पर असिंक्रोनस सर्लेट का समर्थन करता है, (जैसे जैक्स-आरएस या उसके जैसा कुछ जर्सी), मैं नहीं कह सकता। मुझे नहीं पता कि उस स्तर पर कौन से ढांचे का समर्थन कर रहे हैं। ऐसा लगता है कि यह जर्सी 2.0 की एक विशेषता है, जो अभी तक बाहर नहीं है। अन्य लोग भी हो सकते हैं, आपको चारों ओर देखना होगा। साथ ही, सर्वलेट 3.0 पर ठीक न करें। सर्वलेट 3.0 कुछ समय के लिए अलग-अलग कंटेनर में उपयोग की जाने वाली तकनीकों का मानकीकरण है (जेटी विशेष रूप से), ताकि आप केवल सर्वलेट 3.0 के बाहर कंटेनर विशिष्ट विकल्पों को देखना चाहें।

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

+0

का उल्लेख किया गया है, यदि मुझे 5 माइक्रो-सर्विसेज (एम्बेडेड कंटेनर/जेट्टी) चलाने की ज़रूरत है जो कि कतार से जुड़े हैं ताकि वे प्रतिस्पर्धा कर रहे हों स्वयं के बीच (बेहतर थ्रुपुट के लिए) और मेरी क्लाइंट लाइब्रेरी केवल कतार (अनुरोध/प्रतिक्रिया) – TheWhiteRabbit

+0

तक ज़िम्मेदार है, संक्षेप में एसिंक इंटरैक्शन को क्लाइंट लाइब्रेरी का उपयोग करके छुपाया जाना चाहिए जिसे मैं प्रत्येक सेवा के साथ भेजता हूं, मैं एक तकनीकी पसंद की तलाश में हूं उस क्लाइंट लाइब्रेरी के लिए जो सेवा क्लाइंट से HTTP अनुरोध/प्रतिक्रिया मध्यस्थता करता है। – TheWhiteRabbit

+0

मुझे समझ में नहीं आता है। आरईएसटी कॉल करने वाला क्लाइंट एसिंक नहीं होगा, आरईएसटी एक एसिंक आधारित प्रणाली नहीं है। –

2

यदि आप अपनी आवश्यकता को आराम करते हैं कि यह जावा में होना चाहिए, तो आप हैप्रोक्सी पर विचार कर सकते हैं। यह बहुत हल्का, बहुत मानक है, और बहुत अच्छी चीजें करता है (अनुरोध पूलिंग/रखरखाव/कतार) अच्छी तरह से।

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

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

यदि आपका वेब सर्वर बहुत व्यस्त है, तो अनुरोधों को अस्वीकार करना शुरू करें और कुछ अतिरिक्त क्षमता ऑनलाइन प्राप्त करें।

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

0

डिजाइन उपयोग हम एक एक REST इंटरफ़ेस सभी अनुरोध प्राप्त करने और उन्हें एक संदेश कतार (अर्थात RabbitMQ)

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

इस मुख्य नोट की जांच करें, यह इस अवधारणा की शक्ति दिखाता है!

http://www.springsource.org/SpringOne2GX2012

+0

लेकिन अनुरोध/प्रतिक्रिया मॉडल यहां कैसे फिट बैठता है? क्या यह सिंक्रोनस रीक/रेस मॉडल (क्लाइंट प्वाइंट व्यू से) के अनुरूप है? या प्रतिक्रिया के लिए ग्राहक को मतदान की प्रतीक्षा/सुनवाई (घटना के लिए) की जरूरत है? – TheWhiteRabbit

+1

इसके लिए आरईएसटी में कई विकल्प हैं। यानी अगर मैं सेवा कहता हूं और अनुरोध अभी तक संसाधित नहीं किया जा सकता है, तो सर्वर लौटाता है: 202 स्वीकृत। जिसका मतलब है «अनुरोध प्रसंस्करण के लिए स्वीकार कर लिया गया है, लेकिन प्रसंस्करण पूरा नहीं हुआ है।» – moskiteau