Push-Based vs. Pull Based
مطالب آموزشی Event Sourcing:
- بخش اول مقدمهای بر Event Sourcing
- بخش دوم آشنایی مقدماتی با ساختار داخلی Event Store
- مقایسه رویکردهای State-Oriented و State-Transition
- مزیتهای Event Sourcing
- سلام به دنیا به روش Event Sourcing
- سلام به دنیا به روش Event Sourcing-بخش دوم
- بخش هفتم Projection
- ویرایش event ها در EventSourcing
- Message، Command یا Event، کدوم رو انتخاب کنم؟
- بخش دهم: Internal Event vs External Event
- بخش یازدهم: Push-Based-vs-Pull-Based
- مقدمه
در بخش دهم به تفاوت بین Inside Event و Outside Event پرداختم. در این بخش مبحث قبلی را ادامه خواهم داد. این مقاله به این موضوع میپردازد که چگونه میتوان eventها را به دنیای بیرون پابلیش کرد. و چگونه میتوان eventهای پابلیش شده از یک سرویس دیگر را مورد استفاده قرار داد.
- Event
Eventهایی که توسط یک سرویس تولید میشوند از نظر ریزدانگی، و مصرف و همچنین stable بودن با همدیگر متفاوت هستند. بعضی از eventها مصرف داخلی دارند و نیازی نیست که آنها را به دنیای بیرون مخابره کنیم. در مقابل برخی دیگر از eventها مواردی هستند که باید به دنیای بیرون خبر داده شوند. اینها معمولا باعث تریگر شدن یک فرآیند در سایر سرویسها خواهند شد. یکی از راههای تفکیک این eventها همانطور که در بخش دهم دیدیم تفکیک آنها به inside و outside بود. حال سوالی که ممکن است مطرح شود این است که به چه صورت میتوان یک event را به دنیای بیرون پابلیش کرد. راههای متفاوتی برای این کار وجود دارد. در این مقاله به معرفی رویکردهای pull-based و push-based برای پابلیش کردن و استفاده کردن از eventهای یک سرویس به منظور حفط یکپارچکی کلی سیستم، میپردازم. در مقاله آینده به رویکرد inbox-outbox pattern میپردازم.
به این جزئیات که همراه یک event اطلاع رسانی میکنیم، payload میگوئیم. به این event اصطلاحا Carried-State event میگوئیم.
- Push-based Approach
در این رویکرد همانطور از اسمش هم میتوان حدس زد، هر سرویس خود مسئول پابلیش کردن eventهایش است. اینکه این eventها دقیقا کجا باید پابلیش بشوند بسته به سناریو و صورت مسئله متفاوت میباشد.
فرض کنید در سرویسهای پرداخت و مدیریت سفارشات را داشته باشیم.
سرویس مدیریت سفارشات، درخواست پرداخت سفارش را به سرویس مدیریت پرداخت ارسال میکند، و منتظر نتیجه پرداخت خواهد بود. در رویکرد Push-Based سرویس payment پس از پرداخت، نتیجه را به سرویس order management خبر خواهد داد.
کانترکت ارتباطی این سرویسها ممکن است شرایط مختلفی داشته باشد. مثلا ممکن است سرویس پرداخت ReST APIای را در اختیار قرار دهد و سرویس مدیریت سفارشات مستفیما آن را صدا بزند. در اینحالت سرویس مدیریت سفارشات به همراه اطلاعات پرداخت شناسهی سفارش را نیز در اختیار سرویس پرداخت قرار خواهد داد.
پیشنهاد میکنم در سناریوهای شبیه این، کنار اطلاعاتی که به سرویس پرداخت ارسال میکنید، اطلاعاتی در مورد آدرس و نحوهی دریافت پاسخ را نیز قرار دهید. مثلا همانطور که در تصویر بالا مشاهده میکنید reply address نیز به عنوان یک فیلد (معمولا در هدر) قرار داده شده است.
پس از پرداخت سفارش توسط مشتری، سرویس مدیریت پرداخت نتیجه پرداخت را از طریق همین شناسه به اطلاعات سرویس مدیریت سفارشات میرساند. همانطور که مشاهده میکنید سرویس پرداخت همان آدرسی که در درخواست مشخص شده بود را صدا میزند. وضعیت پرداخت در پاسخ ارسالی سرویس پرداخت مشخص شده است. همینطور آدرسی نیز وجود دارد که در صورت نیاز سرویس مدیریت سفارش میتواند اطلاعات تکمیلی پرداخت را نیز استعلام کند.
همانطور که مشاهده میکنید سرویس مدیریت پرداخت، خود مسئول تحویل event مرتبط با پرداخت یک رویداد به سرویس مورد نظر است.
ارتباط بین این دو سرویس ممکن است از طریق یک message broker نیز انجام شود. در اینحالت نیز مکانیزم push-based بصورت مشابه عمل میکند.
در این حالت، یک topic جهت ارسال درخواستهای پرداخت وجود دارد. سرویس پرداخت به این topic گوش میدهد و درخواست را به ترتیب پردازش میکند. نتیجه هر درخواست پرداخت نیز در topic مربوطه به جواب پرداخت قرار داده میشود. سرویس مدیریت پرداخت پس از ارسال درخواست، به topic مربوط به response گوش میدهد تا نتیجه درخواست پرداخت خود را دریافت کند. همانطور که مشاهده میکنید در اینحالت هر سرویس بصورت hybrid هم نقش producer و هم نقش consumer را بازی میکند.
در این سناریو نیز سرویس مدیریت سفارش میتواند در هدر درخواست، آدرس topic مورد نظر که پاسخ باید به آنجا ارسال شود را قرار دهد. با اینکار سرویس پرداخت میتواند پاسخ هر درخواست پرداخت را بسته به نیاز سرویس درخواست دهنده(در اینجا مدیریت سفارشات) به topic متفاوتی ارسال کند. همانطور که مشاهده میکنید صرفنظر از کانترکت و مدیای ارتباطی بین سرویسهای مکانیزم push-based در هر دو سناریو به یک صورت عمل میکند.
- Pull-based Approach
این رویکرد بر عکس روش Push-Based عمل میکند. این به این معنی که سرویسی که علاقمند است به اتفاقاتی که در سرویس دیگر رخ میدهد، خودش در بازههای زمانی مشخصی بصورت فعال استعلام آخرین تغییرات به وقوع پیوسته در آن سرویس میگیرد.
از همان مثال بالا استفاده میکنم تا مطلب را بهتر بتوانم منتقل کنم. در اینجا سرویس مدیریت سفارش درخواستی پرداختی را به سرویس پرداخت ارسال میکند. سرویس پرداخت به محض دریافت پاسخ، پیش از شروع پردازش عملیات پرداخت، درخواست را در صف قرار داده و پاسخی به همراه یک شناسه پیگیری (مجدد پیشنهاد میکنم یک آدرس url جهت پیگیری وضعیت درخواست پرداخت نیز در پاسخ قرار داده شود) به سرویس سرویس مدیریت سفارش بر میگرداند.
سرویس مدیریت سفارش، سپس میتواند از طریق آدرس url که در پاسخ دریافت کرده است، وضعیت پرداخت مورد نظر را استعلام بگیرد. همانطور که مشاهده میکنید در این رویکرد اتفاقات مهمی از جمله پرداخت موفقیت آمیز یک سفارش بصورت مستقیم توسط سرویسی که به آن علاقمند است، از سرویس پرداخت pull میشود.
- مقایسه رویکردهای pull-based و push-based
باید گفت هر کدام از این رویکردها مزایا و معایب و کاربرد خاص خود را دارند. رویکرد push-based از نظر اینکه consumer دیگر مجبور نیست بصورت دورهای event مورد نظر را از سرویس دیگر درخواست کند راحتتر است. اما در این حالت سرویس پرداخت مجبور است بیزنس اضافی را نیز کنترل کند. یعنی پس از هر پرداخت به سرویس مدیریت سفارش وضعیت پرداخت را اعلام کند. هندل کردن این موارد میتواند پیچیدگی زیادی برای هر دو سرویس به همراه داشته باشد.
از طرف دیگر رویکرد pull-based از این نظر که سرویس پرداخت دیگر مجبور نیست که بار اضافی هندل کردن دادن اطلاعات و push کردن eventها به سرویس دیگر را خود به دوش بکشد، رویکرد منعطفتری برای Consumerها محسوب میشود. ولی همانطور که عنوان شد consumerها خود باید بصورت دورهای سراغ سرویسهایی که eventهایی دارند که آنها به آن علاقمند هستند بروند.
پایان بخش یازدهم