एपीआई गेटवे (आरईएसटी) + इवेंट-चालित माइक्रोसर्विसेस


16

मेरे पास माइक्रोसर्विसेस का एक झुंड है जिसकी कार्यक्षमता मैं एपीआई गेटवे पैटर्न के अनुसार रीस्ट एपीआई के माध्यम से उजागर करता हूं। के रूप में इन microservices वसंत बूट आवेदन कर रहे हैं, मैं इन microservices के बीच RPC शैली तुल्यकालिक संचार प्राप्त करने के लिए स्प्रिंग AMQP का उपयोग कर रहा हूँ। हालात अब तक सुचारू रहे हैं। हालाँकि, मैं जितना अधिक इवेंट-संचालित माइक्रोसिस्टवर्क आर्किटेक्चर के बारे में पढ़ता हूं और स्प्रिंग क्लाउड जैसी परियोजनाओं को देखता हूं, उतना अधिक आश्वस्त हो जाता हूं कि मैं आरपीसी के साथ गलत तरीके से काम कर सकता हूं, तुल्यकालिक दृष्टिकोण (विशेषकर क्योंकि मुझे इस पैमाने की आवश्यकता होगी ग्राहक अनुप्रयोगों से प्रति सेकंड सैकड़ों या हजारों अनुरोधों का जवाब देने के लिए)।

मैं एक घटना-संचालित वास्तुकला के पीछे की बात को समझता हूं। जो कुछ मुझे समझ में नहीं आता है वह यह है कि वास्तव में इस तरह के पैटर्न का उपयोग कैसे करें जब एक मॉडल (आरईएसटी) के पीछे बैठे हों जो हर अनुरोध पर प्रतिक्रिया की उम्मीद करता है। उदाहरण के लिए, यदि मेरे पास मेरा एपीआई गेटवे है जो एक माइक्रोसैस सर्विस के रूप में है और एक अन्य माइक्रो-सर्विस जो उपयोगकर्ताओं को स्टोर और प्रबंधित करता है, तो मैं GET /users/1शुद्ध रूप से इवेंट-संचालित फैशन में एक चीज को कैसे मॉडल कर सकता हूं ?

जवाबों:


9

मेरे बाद दोहराएँ:

बाकी और अतुल्यकालिक घटनाएं विकल्प नहीं हैं। वे पूरी तरह से रूढ़िवादी हैं।

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


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

यहाँ खेलने की मुख्य अवधारणा यह है कि स्केलेबल शिथिल-युग्मित दोष-सहिष्णु संदेश को आप जो संदेश भेजते हैं , उससे परिभाषित होता है , न कि आप उन्हें कैसे भेजते हैं । दूसरे शब्दों में, अनुप्रयोग परत पर ढीली युग्मन को परिभाषित किया गया है

आइए दो पार्टियों को सीधे Restful HTTP के साथ या परोक्ष रूप से एक AMQP संदेश ब्रोकर के साथ संवाद करते हुए देखें। मान लीजिए कि पार्टी A पार्टी को JP B में JPEG इमेज अपलोड करना चाहती है जो इमेज को शार्प, कंप्रेस या अन्यथा बढ़ाएगी। पार्टी ए को तुरंत संसाधित छवि की आवश्यकता नहीं है, लेकिन भविष्य में उपयोग और पुनर्प्राप्ति के लिए इसे संदर्भ की आवश्यकता है। यहाँ एक तरीका है जो REST में जा सकता है:

  • पार्टी ए POSTपार्टी बी के साथ एक HTTP अनुरोध संदेश भेजता हैContent-Type: image/jpeg
  • पार्टी ए छवि को संसाधित करता है (लंबे समय तक अगर यह बड़ा है) जबकि पार्टी ए इंतजार करती है, संभवतः अन्य चीजें कर रही हैं
  • पार्टी बी 201 Createdपार्टी ए को एक Content-Location: <url>हेडर के साथ एक HTTP प्रतिक्रिया संदेश भेजता है जो संसाधित छवि से लिंक करता है
  • पार्टी ए अपने काम पर विचार करती है क्योंकि इसमें अब संसाधित छवि का संदर्भ है
  • भविष्य में कभी-कभी जब पार्टी ए को संसाधित छवि की आवश्यकता होती है, तो यह पहले के Content-Locationहेडर से लिंक का उपयोग करके इसे प्राप्त करता है

201 Createdप्रतिक्रिया कोड एक ग्राहक है कि न केवल उनके अनुरोध सफल रहा बताता है, यह भी एक नया संसाधन बनाया। 201 की प्रतिक्रिया में, Content-Locationहेडर निर्मित संसाधन की एक कड़ी है। यह RFC 7231 धारा 6.3.2 और 3.1.4.2 में निर्दिष्ट है।

अब, देखते हैं कि यह बातचीत AMQP के शीर्ष पर एक काल्पनिक RPC प्रोटोकॉल पर कैसे काम करती है:

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

क्या आप यहाँ समस्या देखते हैं? दोनों ही मामलों में पार्टी एक जब तक एक छवि का पता नहीं मिल सकता है के बाद पार्टी बी चित्र को संसाधित । अभी तक पार्टी A को छवि की तुरंत आवश्यकता नहीं है, और सभी अधिकारों द्वारा, यदि प्रक्रिया समाप्त हो गई है तो कम देखभाल नहीं कर सकती है!

एएमक्यूपी मामले में हम इसे आसानी से ठीक कर सकते हैं पार्टी बी को बता दें कि बी ने प्रसंस्करण के लिए छवि को स्वीकार कर लिया है, ए को एक पता दे रहा है जहां प्रसंस्करण पूरा होने के बाद छवि होगी । तब पार्टी बी भविष्य में कुछ समय के लिए एक संदेश भेज सकती है जिससे यह संकेत मिलता है कि छवि प्रसंस्करण समाप्त हो गया है। बचाव के लिए AMQP संदेश!

सिवाय अनुमान के कि क्या: आप उसी चीज को REST के साथ प्राप्त कर सकते हैं । AMQP उदाहरण में हमने "यहाँ की संसाधित छवि" संदेश को "छवि प्रसंस्करण है, आप इसे बाद में प्राप्त कर सकते हैं" संदेश में बदल दिया। Restful HTTP में ऐसा करने के लिए, हम 202 Acceptedकोड का उपयोग करेंगे और Content-Locationफिर:

  • पार्टी ए POSTपार्टी बी के साथ एक HTTP संदेश भेजता हैContent-Type: image/jpeg
  • पार्टी बी तुरंत एक 202 Acceptedप्रतिक्रिया भेजता है जिसमें "असिंक्रोनस ऑपरेशन" सामग्री का कुछ प्रकार होता है जो वर्णन करता है कि क्या प्रसंस्करण समाप्त हो गया है और प्रसंस्करण होने पर छवि उपलब्ध होगी। इसके अलावा एक Content-Location: <link>हेडर भी शामिल है , जो एक 202 Acceptedप्रतिक्रिया में, संसाधन का एक लिंक है, जो कि प्रतिक्रिया निकाय है। इस मामले में, इसका मतलब है कि यह हमारे अतुल्यकालिक ऑपरेशन का एक लिंक है!
  • पार्टी ए अपने काम पर विचार करती है क्योंकि इसमें अब संसाधित छवि का संदर्भ है
  • पार्टी ए को संसाधित छवि की आवश्यकता होने पर भविष्य में कभी-कभी, यह पहले ही तय हो जाता है कि प्रसंस्करण समाप्त हो गया है या नहीं , यह निर्धारित करने के लिए हेडर में लिंक किया गया एस्क्नीक ऑपरेशन संसाधनContent-Location है। यदि ऐसा है, तो पार्टी A संसाधित छवि को प्राप्त करने के लिए स्वयं async ऑपरेशन में लिंक का उपयोग करती है।

यहाँ केवल अंतर यह है कि एएमक्यूपी मॉडल में, पार्टी बी पार्टी ए को बताती है जब छवि प्रसंस्करण किया जाता है। लेकिन REST मॉडल में, पार्टी A चेक करता है कि क्या प्रसंस्करण वास्तव में छवि की आवश्यकता से ठीक पहले किया गया है। ये दृष्टिकोण समान रूप से स्केलेबल हैं । जैसे-जैसे सिस्टम बड़ा होता जाता है, दोनों एसिंक्स एएमक्यूपी में भेजे गए संदेशों की संख्या और एसिंक्स रीस्ट की रणनीतियों में समान विषमता की जटिलता बढ़ जाती है। फर्क सिर्फ इतना है कि क्लाइंट सर्वर के बजाय एक अतिरिक्त संदेश भेज रहा है।

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

खैर, HTTP वास्तव में इसके लिए पहले से ही एक मानकीकृत प्रोटोकॉल है! इसे HTTP प्राथमिकताएं कहा जाता है, विशेष रूप respond-asyncसे RFC 7240 धारा 4.1 की प्राथमिकता। यदि पार्टी A अतुल्यकालिक प्रतिक्रिया की इच्छा रखती है, तो इसमें Prefer: respond-asyncअपने प्रारंभिक POST अनुरोध के साथ एक हेडर शामिल होता है । यदि पार्टी बी इस अनुरोध का सम्मान करने का निर्णय लेती है, तो वह एक 202 Acceptedप्रतिक्रिया वापस भेजती है जिसमें एक शामिल है Preference-Applied: respond-async। अन्यथा, पार्टी बी केवल Preferहेडर को अनदेखा करती है और वापस भेजती है 201 Createdजैसा कि सामान्य रूप से होता है।

यह पार्टी ए को सर्वर के साथ बातचीत करने की अनुमति देता है, गतिशील रूप से जो भी छवि प्रसंस्करण कार्यान्वयन के लिए बात करता है, उसके साथ बात करता है। इसके अलावा, स्पष्ट लिंक्स के उपयोग का मतलब है कि पार्टी A को B के अलावा किसी भी पक्ष के बारे में पता नहीं है: कोई AMQP संदेश दलाल, कोई रहस्यमय पार्टी C जो वास्तव में छवि पते को छवि डेटा में बदलना नहीं जानता, कोई दूसरा B- Async नहीं है पार्टी अगर तुल्यकालिक और अतुल्यकालिक दोनों अनुरोध किए जाने की आवश्यकता है, आदि। यह केवल यह बताता है कि इसे क्या चाहिए, यह वैकल्पिक रूप से क्या पसंद करेगा, और फिर स्थिति कोड, प्रतिक्रिया सामग्री और लिंक पर प्रतिक्रिया करता है। जोड़ेंCache-Controlडेटा की स्थानीय प्रतियाँ रखने के बारे में स्पष्ट निर्देशों के लिए हेडर, और अब सर्वर क्लाइंट के साथ बातचीत कर सकते हैं कि कौन से संसाधन ग्राहक स्थानीय (या ऑफ़लाइन भी हो सकते हैं!) प्रतियां। इस प्रकार आप REST में शिथिल-युग्मित दोष-सहिष्णु microservices का निर्माण करते हैं।


1

आपको विशुद्ध रूप से संचालित होने की आवश्यकता है या नहीं, यह आपके विशिष्ट परिदृश्य पर निर्भर करता है। यह मानते हुए कि आपको वास्तव में होना चाहिए, तब आप समस्या को हल कर सकते हैं:

विभिन्न घटनाओं को सुनने और उनके पेलोड में जानकारी कैप्चर करके डेटा की एक स्थानीय, केवल-पढ़ने की प्रतिलिपि संग्रहीत करना । जबकि यह आपको उस डेटा के लिए तेजी से (एर) रीड करता है, जो उस सटीक एप्लिकेशन के लिए उपयुक्त रूप में संग्रहीत होता है, इसका मतलब यह भी है कि आपका डेटा अंततः सेवाओं के अनुरूप होगा।

GET /users/1इस दृष्टिकोण के साथ मॉडल करने के लिए , कोई भी UserCreatedऔर UserUpdatedईवेंट के लिए सुन सकता है , और सेवा में उपयोगकर्ता डेटा के उपयोगी सबसेट को संग्रहीत कर सकता है। जब आपको उस उपयोगकर्ता की जानकारी प्राप्त करने की आवश्यकता होती है, तो आप बस अपने स्थानीय डेटा स्टोर को क्वेरी कर सकते हैं।

एक मिनट के लिए, मान लें कि सेवा जो /users/समापन बिंदु को उजागर करती है, वह किसी भी प्रकार की घटनाओं को प्रकाशित नहीं करती है। इस उदाहरण में, आप अपने द्वारा किए गए HTTP अनुरोधों के लिए बस प्रतिक्रियाओं को कैशिंग करके एक समान चीज़ प्राप्त कर सकते हैं, इस प्रकार कुछ समय सीमा के भीतर प्रति उपयोगकर्ता 1 से अधिक HTTP अनुरोध करने की आवश्यकता को नकारते हैं।


मै समझता हुँ। लेकिन इस परिदृश्य में ग्राहकों को त्रुटि से निपटने (और रिपोर्टिंग) के बारे में क्या?
टोनी ई। स्टार्क

मेरा मतलब है, मैं REST क्लाइंट त्रुटियों की रिपोर्ट कैसे करूं, जो UserCreatedईवेंट को हैंडल करते समय होती हैं (उदाहरण के लिए, डुप्लिकेट उपयोगकर्ता नाम या ईमेल या डेटाबेस आउटेज)।
टोनी ई। स्टार्क

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

0

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.