نمونه کد با الگوی Saga

قصد داریم در این مقاله مختصر توضیحاتی در خصوص پیاده‌سازی یک پروژه ساده با بهره‌گیری از الگوی Saga را خدمت شما ارائه دهیم.معرفی پروژه :در این پروژه ما یک سرویس سفارش‌دهی داریم که روند آن بدین‌صورت است که کاربر محصولات را مشاهده نموده و سپس محصول مورد نظر خود را انتخاب می‌کند. پس از انتخاب به قسمت پرداخت هدایت شده و در صورتی‌که پرداخت موفقیت آمیز باشد، محصول مذکور برای کاربر ثبت می‌شود.تکنولوژی‌ها :Spring BootPostgreSQLRabbitMQمقدمه :قبل از شروع لازم می‌دانیم که مختصر توضیحاتی در خصوص نحوه‌ی پیاده‌سازی پروژه به شما بدیم.این پروژه به صورت Microservice نوشته شده و هر سرویس از معماری 3Tier layer بهره برده و سرویس‌ها برای ارتباط با یکدیگر از الگوی Saga و ابزار RabbitMQ استفاده می‌کنند.الگوی Saga چیست؟الگوی Saga یکی از 6 الگوی مهم مدیریت داده‌های Microservice است که می‌توان آن را نتیجه‌ی مستقیم الگوی Database-per-service دانست. در الگوی Database-per-service، هر Microservice مسئول داده‌های خود است. بااین‌حال سؤال اینجاست که چه اتفاقی می‌افتد اگر یک Transaction شامل داده‌هایی باشد که در چندین Microservice وجود دارد؟ در این موقعیت‌هاست که نیاز به الگوی Saga پدید می‌آید.الگوی Saga به‌عنوان الگوی معماری Microservice ها برای پیاده‌سازی Transaction هایی است که شامل چندین سرویس هستند. Saga توالی Microservice ها است. هر سرویس در یک Saga، Transaction خود را انجام داده و رویدادی را منتشر می‌کند. سایر سرویس‌ها به آن رویداد گوش می‌دهند و Transaction محلی بعدی را انجام می‌دهند. اگر به یک دلیل Transaction ای ناموفق باشد، این الگو، به‌منظور خنثی کردن تأثیر Transaction های قبلی، Transaction های Compensating یا جبران کننده را اجرا می‌کند.ابزار RabbitMQ چیست ؟ابزار RabbitMQ، پیاده‌سازی یک واسط تبادل پیام است که اغلب به‌عنوان Service bus شناخته می‌شود. این ابزار از پیام‌های Classic که از Queue خارج می‌شوند پشتیبانی می‌کند. یک Developer Queue های نام‌گذاری شده ‌ای را تعریف می‌کند که Publisher ها می‌توانند پیام‌های خود را به آن‌ ها ارسال کنند. Consumer ها نیز از همان Queue ها برای برداشتن پیام به ‌منظور پردازش استفاده می‌کنند.حال می‌خواهیم توسط توضیحاتی که دادیم پروژه هدف را شرح دهیم:پروژه‌ی ما شامل ۴ بخش و ۳ سرویس زیر است :سرویس Order :همان‌طور که پیش‌تر توضیح دادیم ما در این پروژه از الگوی Saga و یا به زبان دیگر از event ها استفاده می‌کنیم. بدین صورت که در سرویس Order سه event با نام‌های زیر تعریف کردیم.OrderCanceledEventHandlerOrderDoneEventHandlerOrderEventListenerدر کلاس OrderService، پس از دریافت سفارش و ثبت آن، توسط تابع زیر سفارش ثبت شده را publish می‌کنیم.ما گفتیم که روند ثبت سفارش بدین صورت است که پس از ثبت در یک queue، سفارش publish می‌شود. ممکن است سوال پیش‌بیاید که در چه queueای و به چه صورت؟پاسخ در کلاس OrderEventListener است:به TransactionalEventListener Annotation توجه کنید. این ابزار به ما این امکان را می‌دهد که هنگامی که یک Transaction به صورت commit درآمد بر روی queue خواسته شده (که در این بخش با نام queue.order-create ثبت شده) یک مقداری را publish کند.سرویس Payment :همان‌طور که در تصویر بالا مشاهده می‌کنید این سرویس هیچ کنترلری نداشته و تنها با listen کردن به queueها کار می‌کند.در کلاس بالا، توسط RabbitListener Annotation به queue با نام queue.order-create گوش می‌دهیم.هنگامی که مقداری در این queue توسط هر سرویسی publish شد، این annotation فعال شده و تابع handle را اجرا می‌کند.نکته‌ای که در اینجا قابل اشاره است، هنگامی که قصد داریم مقداری را در queueها بفرستیم، می‌بایست به صورت object دارورده و سپس در queue قرار دهیم. همچنین در آن سوی queue این object را مجدد به کلاس خودش convert کنیم.این عملیات convert کردن پیش از ارسال به queue و پس از دریافت از آن را سرویس Shared برعهده دارد.سرویس Stock :این سرویس نیز مانند سرویس‌ payment کنترلری نداشته و تنها با event ها کار می‌کند.ما سعی نمودیم در این پروژه‌ی کاربردی چگونگی پیاده‌سازی و استفاده از الگوی Saga در Microservice را خدمت شما ارائه دهیم.پیشنهاد می‌کنیم جهت درک بهتر، کد را به صورت کامل از صفحه github ما مشاهده نمایید.در صورتی‌که انتقاد و یا پیشنهادی دارید، در قسمت نظرات ما را مطلع نمایید. همچنین می‌توانید برای دسترسی به کدهای بیشتر از سایت ما دیدن کنید.