REST माइक्रोसर्विसेज में लेनदेन?




architecture transactions (7)

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

अब यहाँ कुछ परिदृश्य हैं जहाँ चीजें गलत हो सकती हैं:

  • उपयोगकर्ता बॉब निर्माण विफल रहता है: यह ठीक है, हम सिर्फ बॉब को एक त्रुटि संदेश लौटाते हैं। हम एसक्यूएल लेनदेन का उपयोग कर रहे हैं ताकि कोई भी बॉब को सिस्टम में न देखे। सब कुछ अच्छा है :)

  • उपयोगकर्ता बॉब बनाया गया है, लेकिन इससे पहले कि हमारा वॉलेट बनाया जा सके, हमारा एपीआई गेटवे हार्ड क्रैश हो जाता है। अब हमारे पास एक उपयोगकर्ता है जिसमें कोई बटुआ (असंगत डेटा) नहीं है।

  • उपयोगकर्ता बॉब बनाया गया है और जैसा कि हम वॉलेट बना रहे हैं, HTTP कनेक्शन ड्रॉप हो जाता है। बटुआ निर्माण सफल हो सकता है या यह नहीं हो सकता है।

इस तरह की डेटा असंगतता को रोकने के लिए कौन से समाधान उपलब्ध हैं? क्या ऐसे पैटर्न हैं जो लेनदेन को कई REST अनुरोधों को पूरा करने की अनुमति देते हैं? मैंने विकिपीडिया पृष्ठ को दो-चरण की प्रतिबद्धताओं पर पढ़ा है जो इस मुद्दे पर स्पर्श करता है लेकिन मुझे यकीन नहीं है कि इसे व्यवहार में कैसे लागू किया जाए। यह परमाणु वितरित लेनदेन: एक प्रतिष्ठित डिज़ाइन पेपर भी दिलचस्प लगता है, हालांकि मैंने इसे अभी तक नहीं पढ़ा है।

वैकल्पिक रूप से, मुझे पता है कि REST इस उपयोग के मामले के लिए उपयुक्त नहीं हो सकता है। शायद इस स्थिति को संभालने का सही तरीका है कि REST को पूरी तरह से छोड़ दें और एक संदेश कतार प्रणाली की तरह एक अलग संचार प्रोटोकॉल का उपयोग करें? या क्या मुझे अपने आवेदन कोड में स्थिरता लागू करनी चाहिए (उदाहरण के लिए, एक पृष्ठभूमि नौकरी होने से जो विसंगतियों का पता लगाता है और उन्हें ठीक करता है या "बनाने", "बनाया गया" मान, आदि) के साथ मेरे उपयोगकर्ता मॉडल पर "स्थिति" विशेषता है?


इस तरह की डेटा असंगतता को रोकने के लिए कौन से समाधान उपलब्ध हैं?

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

क्या ऐसे पैटर्न हैं जो लेनदेन को कई REST अनुरोधों को पूरा करने की अनुमति देते हैं?

SOAP (ठीक है, REST नहीं) के लिए, WS-AT विनिर्देश है, लेकिन मुझे कभी भी एकीकृत करने वाली कोई सेवा समर्थन नहीं है। REST के लिए, JBoss की पाइपलाइन में कुछ है । अन्यथा, "पैटर्न" या तो एक उत्पाद ढूंढना है जिसे आप अपनी वास्तुकला में प्लग कर सकते हैं, या अपने स्वयं के समाधान का निर्माण कर सकते हैं (अनुशंसित नहीं)।

मैंने जावा ईई: https://github.com/maxant/genericconnector लिए ऐसा उत्पाद प्रकाशित किया है

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

BPEL इंजन मुआवजे का उपयोग कर दूर से तैनात सेवाओं के बीच स्थिरता को संभालता है।

वैकल्पिक रूप से, मुझे पता है कि REST इस उपयोग के मामले के लिए उपयुक्त नहीं हो सकता है। शायद इस स्थिति को संभालने का सही तरीका है कि REST को पूरी तरह से छोड़ दें और एक संदेश कतार प्रणाली की तरह एक अलग संचार प्रोटोकॉल का उपयोग करें?

गैर-लेन-देन संसाधनों को "बाध्यकारी" करने के कई तरीके हैं:

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

या क्या मुझे अपने आवेदन कोड में स्थिरता लागू करनी चाहिए (उदाहरण के लिए, एक पृष्ठभूमि नौकरी होने से जो विसंगतियों का पता लगाता है और उन्हें ठीक करता है या "उपयोगकर्ता" पर "स्टेट" विशेषता "बनाने", "बनाया" मान, आदि) के साथ है?

डेविल्स की वकालत करना: ऐसा कुछ क्यों बनाएं, जब ऐसे उत्पाद हों जो आपके लिए हैं (ऊपर देखें), और शायद इसे आप जितना कर सकते हैं, उससे बेहतर करें, क्योंकि उन्हें आज़माया और परखा जाता है?


API प्रबंधन (APIM) प्लेटफ़ॉर्म का उपयोग क्यों न करें जो स्क्रिप्टिंग / प्रोग्रामिंग का समर्थन करता है? तो, आप सूक्ष्म सेवाओं को परेशान किए बिना APIM में समग्र सेवा का निर्माण करने में सक्षम होंगे। मैंने इस उद्देश्य के लिए APIGEE का उपयोग करके डिज़ाइन किया है।


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


माइक्रोसर्विस आर्किटेक्चर के प्रमुख पहलुओं में से एक IMHO यह है कि लेन-देन व्यक्तिगत माइक्रो सर्विस (एकल जिम्मेदारी सिद्धांत) तक ही सीमित है।

वर्तमान उदाहरण में, उपयोगकर्ता निर्माण स्वयं लेनदेन होगा। उपयोगकर्ता निर्माण एक USER_CREATED घटना को एक कतार में धकेल देगा। वॉलेट सेवा USER_CREATED ईवेंट की सदस्यता लेगी और वॉलेट निर्माण करेगी।


यह एक क्लासिक प्रश्न है जो मुझे हाल ही में एक साक्षात्कार के दौरान पूछा गया था कि कैसे कई वेब सेवाओं को कॉल किया जाए और फिर भी कार्य के बीच में किसी प्रकार की त्रुटि से निपटने के लिए सुरक्षित रखें। आज, उच्च प्रदर्शन कंप्यूटिंग में, हम दो चरण के कमिट्स से बचते हैं। मैंने लेन-देन के लिए "स्टारबक मॉडल" कहा जाने वाला एक पेपर कई साल पहले पढ़ा था: स्टारबक में आपके द्वारा ऑर्डर किए गए कॉफी का ऑर्डर देने, भुगतान करने, तैयार करने और प्राप्त करने की प्रक्रिया के बारे में सोचें ... मैं चीजों की देखरेख करता हूं लेकिन एक दो चरण वाला मॉडल। सुझाव दें कि पूरी प्रक्रिया में शामिल सभी चरणों के लिए एक एकल रैपिंग लेनदेन होगा जब तक आप अपनी कॉफी प्राप्त नहीं करते। हालांकि, इस मॉडल के साथ, सभी कर्मचारी इंतजार करेंगे और तब तक काम करना बंद कर देंगे जब तक आप अपनी कॉफी नहीं लेते। आप तस्वीर देखिए?

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

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

  • अपनी वेब सेवाओं को परिभाषित करते समय बहुत ठीक न हों (मैं इन दिनों हो रही सूक्ष्म-सेवा प्रचार के बारे में आश्वस्त नहीं हूं: बहुत दूर जाने के कई जोखिम);

  • Async प्रदर्शन बढ़ाता है इसलिए async होना पसंद करते हैं, जब भी संभव हो ईमेल द्वारा सूचनाएं भेजें।

  • किसी भी संख्या में उन्हें "वापस लेने योग्य" बनाने के लिए अधिक बुद्धिमान सेवाओं का निर्माण करें, एक यूआईडी या टास्किड के साथ प्रसंस्करण जो अंत तक शीर्ष क्रम का पालन करेगा, प्रत्येक चरण में व्यावसायिक नियमों को मान्य करेगा;

  • संदेश कतारों (JMS या अन्य) का उपयोग करें और त्रुटि से निपटने वाले प्रोसेसर पर डायवर्ट करें जो विपरीत कार्यों को लागू करने के लिए "रोलबैक" पर काम करेंगे, वैसे, async आदेश के साथ काम करने के लिए प्रक्रिया की वर्तमान स्थिति को मान्य करने के लिए किसी प्रकार की कतार की आवश्यकता होगी। तो विचार करें कि;

  • अंतिम उपाय में, (क्योंकि यह अक्सर नहीं हो सकता है), इसे त्रुटियों के मैनुअल प्रसंस्करण के लिए एक कतार में रखें।

चलिए पोस्ट की गई प्रारंभिक समस्या के साथ वापस चलते हैं। एक खाता बनाएं और एक वॉलेट बनाएं और सुनिश्चित करें कि सब कुछ किया गया था।

मान लीजिए कि एक वेब सेवा को पूरे ऑपरेशन को ऑर्केस्ट्रेट करने के लिए कहा जाता है।

वेब सेवा का छद्म कोड इस तरह दिखेगा:

  1. खाता सृजन माइक्रोसर्विस को कॉल करें, इसे कुछ जानकारी दें और कुछ यूनीक टास्क आईडी 1.1 खाता सृजन माइक्रोसर्विस पहले यह जांच करेगा कि क्या वह खाता पहले ही बनाया गया था। एक कार्य आईडी खाते के रिकॉर्ड के साथ जुड़ा हुआ है। Microservice पता लगाता है कि खाता मौजूद नहीं है इसलिए यह इसे बनाता है और कार्य आईडी को संग्रहीत करता है। ध्यान दें: इस सेवा को 2000 बार कहा जा सकता है, यह हमेशा एक ही परिणाम करेगा। सेवा "रसीद के साथ जवाब देती है जिसमें आवश्यक होने पर एक पूर्ववत ऑपरेशन करने के लिए न्यूनतम जानकारी होती है"।

  2. वॉलेट निर्माण को कॉल करें, यह खाता आईडी और कार्य आईडी दे रहा है। मान लीजिए कि कोई शर्त मान्य नहीं है और वॉलेट निर्माण नहीं किया जा सकता है। कॉल त्रुटि के साथ देता है लेकिन कुछ भी नहीं बनाया गया था।

  3. ऑर्केस्ट्रेटर को त्रुटि के बारे में बताया जाता है। यह जानता है कि इसे खाता निर्माण को निरस्त करने की आवश्यकता है लेकिन यह स्वयं ऐसा नहीं करेगा। यह चरण 1 के अंत में प्राप्त की गई "न्यूनतम पूर्ववत रसीद" पास करके वॉलेट सेवा को करने के लिए कहेगा।

  4. खाता सेवा पूर्ववत रसीद को पढ़ती है और यह जानती है कि ऑपरेशन को कैसे करना है; पूर्ववत रसीद में एक और माइक्रोसर्विस के बारे में जानकारी भी शामिल हो सकती है जिसे वह खुद को नौकरी का हिस्सा बनाने के लिए कह सकता है। इस स्थिति में, पूर्ववत रसीद में खाता आईडी हो सकता है और संभवतः विपरीत ऑपरेशन करने के लिए कुछ अतिरिक्त जानकारी की आवश्यकता होती है। हमारे मामले में, चीजों को सरल बनाने के लिए, मान लें कि खाता अपनी खाता आईडी का उपयोग करके हटा दिया गया है।

  5. अब, मान लें कि वेब सेवा को कभी भी सफलता या विफलता नहीं मिली (इस मामले में) कि खाता निर्माण का पूर्ववत प्रदर्शन किया गया था। यह बस खाते की पूर्ववत सेवा को फिर से कॉल करेगा। और यह सेवा सामान्य नहीं होनी चाहिए क्योंकि इसका लक्ष्य खाते के लिए मौजूद नहीं है। तो यह जाँचता है कि क्या यह मौजूद है और देखता है कि इसे पूर्ववत करने के लिए कुछ भी नहीं किया जा सकता है। तो यह रिटर्न करता है कि ऑपरेशन एक सफलता है।

  6. वेब सेवा उस उपयोगकर्ता को लौटा देती है जो खाता नहीं बना सका।

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

मैंने एक खोज की है और Microsoft वेब साइट पर इस दृष्टिकोण के लिए एक पैटर्न विवरण है। इसे क्षतिपूर्ति लेनदेन पैटर्न कहा जाता है:

लेन-देन का पैटर्न


व्यक्तिगत रूप से मुझे माइक्रो सर्विसेज का विचार पसंद है, उपयोग के मामलों से परिभाषित मॉड्यूल, लेकिन जैसा कि आपके प्रश्न का उल्लेख है, उनके पास बैंक, बीमा, दूरसंचार, आदि जैसे शास्त्रीय व्यवसायों के लिए अनुकूलन समस्याएं हैं ...

वितरित लेनदेन, जैसा कि कई उल्लेख किया गया है, एक अच्छा विकल्प नहीं है, लोग अब अंततः सुसंगत प्रणालियों के लिए अधिक जा रहे हैं, लेकिन मुझे यकीन नहीं है कि यह बैंकों, बीमा, आदि के लिए काम करेगा।

मैंने अपने प्रस्तावित समाधान के बारे में एक ब्लॉग लिखा है, हो सकता है कि यह आपकी मदद कर सकता है ...।

https://mehmetsalgar.wordpress.com/2016/11/05/micro-services-fan-out-transaction-problems-and-solutions-with-spring-bootjboss-and-netflix-eureka/


क्या मतलब नहीं है:

  • अन्य सेवाओं के साथ लेनदेन का वितरण किया । परिभाषा के अनुसार अन्य सेवाएं स्टेटलेस हैं, इसलिए उन्हें एक ट्रांजेक्शनल सीमा में भागीदार नहीं होना चाहिए जो एक से अधिक सेवा प्रदान करता है। आपका उपयोगकर्ता पंजीकरण उपयोग मामला परिदृश्य समझ में आता है, लेकिन उपयोगकर्ता और वॉलेट डेटा बनाने के लिए REST माइक्रोसर्विसेज के साथ डिज़ाइन अच्छा नहीं है।

आपको सिरदर्द क्या देगा:

  • वितरित लेनदेन के साथ EJBs । यह उन चीजों में से एक है जो सिद्धांत में काम करते हैं लेकिन व्यवहार में नहीं। अभी मैं JBoss EAP 6.3 उदाहरणों में दूरस्थ EJBs के लिए एक वितरित लेनदेन कार्य करने का प्रयास कर रहा हूँ। हम RedHat सहायता के लिए हफ्तों से बात कर रहे हैं, और यह अभी तक काम नहीं किया है।
  • सामान्य तौर पर दो-चरण प्रतिबद्ध समाधान । मुझे लगता है कि 2PC प्रोटोकॉल एक महान एल्गोरिथ्म है (कई साल पहले मैंने इसे RPC के साथ C में लागू किया था)। इसके लिए रिट्रीट, स्टेट रिपॉजिटरी आदि के साथ व्यापक फेल रिकवरी मैकेनिज्म की आवश्यकता होती है। सभी जटिलता ट्रांजेक्शन फ्रेमवर्क के भीतर छिपी हुई है (उदाहरण: JBoss Arjuna)। हालांकि, 2PC फेल प्रूफ नहीं है। ऐसी स्थितियां हैं, जिनमें लेन-देन आसानी से पूरा नहीं हो सकता है। फिर आपको डेटाबेस की विसंगतियों को मैन्युअल रूप से पहचानने और ठीक करने की आवश्यकता है। यदि आप भाग्यशाली हैं, तो यह एक लाख लेनदेन में एक बार हो सकता है, लेकिन यह आपके प्लेटफॉर्म और परिदृश्य के आधार पर प्रत्येक 100 लेनदेन में एक बार हो सकता है।
  • सगास (लेन-देन का मुआवजा) । क्षतिपूर्ति संचालन बनाने के लिए कार्यान्वयन ओवरहेड है, और अंत में मुआवजे को सक्रिय करने के लिए समन्वय तंत्र है। लेकिन मुआवजा विफल सबूत भी नहीं है। आप अभी भी विसंगतियों (कुछ सिरदर्द) के साथ समाप्त हो सकते हैं।

क्या शायद सबसे अच्छा विकल्प है:

  • आखिरकार संगति । न तो ACID जैसे वितरित लेनदेन और न ही क्षतिपूर्ति लेनदेन विफल प्रमाण हैं, और दोनों से असंगतता हो सकती है। अंततः संगति अक्सर "सामयिक असंगति" से बेहतर होती है। विभिन्न डिजाइन समाधान हैं, जैसे:
    • आप अतुल्यकालिक संचार का उपयोग करके अधिक मजबूत समाधान बना सकते हैं। आपके परिदृश्य में, जब बॉब रजिस्टर करता है, तो एपीआई गेटवे न्यूयूजर कतार में एक संदेश भेज सकता है, और उपयोगकर्ता को यह कहते हुए सही उत्तर दे सकता है कि "आपको खाता निर्माण की पुष्टि करने के लिए एक ईमेल प्राप्त होगा।" एक कतार उपभोक्ता सेवा संदेश को संसाधित कर सकती है, एक एकल लेनदेन में डेटाबेस परिवर्तन कर सकती है और खाता निर्माण को सूचित करने के लिए ईमेल को बॉब को भेज सकती है।
    • उपयोगकर्ता माइक्रोसैसवर्क उसी डेटाबेस में उपयोगकर्ता रिकॉर्ड और वॉलेट रिकॉर्ड बनाता है। इस स्थिति में, उपयोगकर्ता microservice में वॉलेट स्टोर केवल वॉलेट क्रॉसवर्ड के लिए दिखाई देने वाले मास्टर वॉलेट स्टोर की प्रतिकृति है। एक डेटा सिंक्रोनाइज़ेशन मैकेनिज़्म है जो समय-समय पर ट्रिगर-आधारित या किक्स होता है, जो प्रतिकृति से मास्टर, और इसके विपरीत डेटा परिवर्तन (जैसे, नए पर्स) भेजने के लिए होता है।

लेकिन क्या होगा यदि आपको सिंक्रोनस प्रतिक्रियाओं की आवश्यकता है?

  • Microservices फिर से तैयार करें । यदि कतार के साथ समाधान काम नहीं करता है, क्योंकि सेवा उपभोक्ता को तुरंत प्रतिक्रिया की आवश्यकता है, तो मैं उसी सेवा में उपयोगकर्ता (और कम से कम एक ही वीएम) में वितरित लेनदेन से बचने के लिए उपयोगकर्ता और वॉलेट कार्यक्षमता को फिर से तैयार करूंगा। )। हां, यह माइक्रोसर्विस से एक कदम आगे है और एक मोनोलिथ के करीब है, लेकिन आपको कुछ सिरदर्द से बचाएगा।






microservices