الگوی ساگا (Saga Pattern)


10 تا الگوی مهم در طراحی میکروسرویس هست که باید بلد باشید که بتونید ساختار مایکروسرویس های خودتون رو به خوبی پیاده سازی کنید.

1-Database per service pattern
2-Saga pattern
3-API gateway pattern
4-Aggregator design pattern
5-Circuit breaker design pattern
6-Command query responsibility segregation (CQRS)
7-Asynchronous messaging
8-Event sourcing
9-Strangler
10-Decomposition patterns

سرویس هاتون نیاز به رهبر دارن یا رقص رو خوب بلدن ؟؟!!!
یه نکته طلایی همین اول بگیم ذهنتون درگیر بشه بعد بریم شروع کنیم :
توی Choreography سرویس‌ها خودشون "رقص" رو بلدن
ولی توی Orchestration یه رهبر ارکستر (Orchestrator) هست که می‌گه کی چی بزنه 😄



الگوی ساگا (Saga Pattern):

ساگا مجموعه‌ای از تراکنش‌های محلی (Local Transactions) است. در اپلیکیشن‌های مبتنی بر میکروسرویس، الگوی ساگا می‌تواند به حفظ یکپارچگی داده‌ها (maintain data) در تراکنش‌های توزیع‌شده (distributed transactions) کمک کند.

الگوی ساگا یک راه‌حل جایگزین برای سایر الگوهای طراحی است که امکان اجرای چندین تراکنش را فراهم می‌کند، در حالی که فرصت‌هایی برای بازگردانی (Rollback) در صورت بروز خطا نیز فراهم می‌سازد.

به‌بیان ساده، به‌جای اینکه یک تراکنش بزرگ و مرکزی بین چند سرویس اجرا شود، ساگا هر عملیات را در قالب تراکنش‌های جداگانه اما مرتبط اجرا می‌کند. اگر این وسط زبونم لال یکی از تراکنش‌ها با خطا مواجه شود، عملیات‌های جبرانی (Compensating Actions) اجرا می‌شوند تا سیستم به وضعیت سازگار قبلی بازگردد.

دوتا روش پیاده سازی داریم :

۱. Choreography (هماهنگی غیرمتمرکز):

در این روش، هر سرویس پس از انجام یک تراکنش، یک رویداد (Event) منتشر می‌کند. سایر سرویس‌ها به این رویدادها گوش می‌دهند و طبق دستوراتی که برایشان نوشته شده عمل می‌کنند. خود این اقدامات ممکنه رویداد جدیدی منتشر کنند یا نکنند.

۲. Orchestration (هماهنگی متمرکز):

در این رویکرد، یک "هماهنگ‌کننده" (Orchestrator) مسئول اجرای تراکنش‌ها و مدیریت رویدادها است.
به سایر سرویس‌ها اعلام میکنه که چه تراکنش‌های محلی را اجرا کنند.
در واقع Orchestrator مانند رهبر ارکستر عمل می‌کند و اجرای مراحل مختلف را کنترل می‌کند.

الگوی ساگا یکم پیچیده و سخته و پیاده‌سازی موفق و کاملش مهارت بالایی میخواد. شاید جایی که الان هستید پیاده سازی شده باشه برید ببینید چطوری نوشتنش یاد بگیرید.
یه مزیت بزرگش اینه که بدون ایجاد coupling زیاد بین سرویس‌ها، میتونیم انسجام داده‌ها ( maintained data ) رو حفظ کنیم.




بیاید با یه مثال هر کدوم از این دوتا روش رو بهتر بشناسیم :

یه نکته رو بگم Orchestration رو لطفا با Api Gateway اشتباه نگیرید کارشون متفاوته سعی میکنم یه مثال براش بزنم .

فرض کنید یه فروشگاه اینترنتی دارید و فرض کنید که چنتا مایکروسرویس داریم (خیلی خفنه فروشگاهمون):

  1. Order Service → ثبت سفارش
  2. Inventory Service → بررسی و رزرو موجودی
  3. Payment Service → انجام پرداخت
  4. Shipping Service → ارسال محصول
  5. Notification Service → ارسال پیام های مرتبط به مشتری (پیامک ، ایمیل و ...)


Choreography :


بریم سراغ Choreography که کاملاً غیرمتمرکز هست و بر پایه Event-Driven Architecture کار می‌کنه.

ما تو روش Choreography، هیچ Orchestrator مرکزی نداریم. هر سرویس فقط به رویدادهای منتشرشده گوش می‌ده و در صورت نیاز، واکنش نشون می‌ده.

برای event هم مثلا از RabbitMQ یا Kafka استفاده میکنیم .

مراحل اجرا :

کاربر میاد یه سفارش ثبت میکنه . مسئولیت ثبت سفارش به عهده Order Service هست .
Order Service سفارش رو در دیتابیس ذخیره می‌کنه.
و یه رویداد OrderCreated منتشر می‌کنه.
نکته میتونیم رویداد هامون رو نام گذاری کنیم و هر رویداد برای کار خاصی باشه . تصمیم با خودتونه ("OrderCreated":"event")
این پایین یه نمونه از رویداد ایجاد شده رو میبینید.

{
  &quotevent&quot: &quotOrderCreated&quot,
  &quotdata&quot: {
    &quotorderId&quot: &quot123&quot,
    &quotuserId&quot: &quot456&quot,
    &quotproductId&quot: &quotabc&quot,
    &quotquantity&quot: 2,
    &quottotalPrice&quot: 500000
  }
}

همه سرویس ها در حال گوش دادن به رویداد مورد نظر خودشون هستن .

در این مرحله Inventory Service که داره به رویداد OrderCreated گوش میده.
وقتی این رویداد رو دید:

  • بررسی می‌کنه موجودی کافی هست یا نه
  • اگه کافی بود، موجودی رو رزرو می‌کنه
  • رویداد InventoryReserved منتشر می‌کنه

در این مرحله Payment Service داره به رویداد InventoryReserved گوش میده .

وقتی این رویداد رو دید:

  • پرداخت رو انجام می‌ده (مثلاً از کیف پول کاربر)
  • اگه موفق بود، رویداد PaymentSucceeded منتشر می‌کنه
  • اگه ناموفق بود، رویداد PaymentFailed منتشر می‌کنه

در مرحله آخر هم Shipping Service داره به رویداد PaymentSucceeded گوش میده .

وقتی این رویداد رو دید:

  • عملیات ارسال رو آغاز می‌کنه
  • رویداد OrderShipped منتشر می‌کنه


در صورت خطا چه میشه؟

مثلاً اگر PaymentFailed اتفاق بیفته:
Inventory Service می‌تونه به PaymentFailed گوش بده و موجودی رو آزاد کنه و رویداد InventoryReleased رو منتشر کنه .
Order Service می‌تونه سفارش رو به وضعیت "ناموفق" ببره

جمله مهمی که اول گفتم : توی Choreography سرویس‌ها خودشون "رقص" رو بلدن

Orchestration :

یک سرویس مرکزی (به‌نام Orchestrator) تصمیم می‌گیره چه کاری انجام بشه، به کدوم سرویس‌ها پیام بده، به چه ترتیبی این کارها انجام بشن، و اگه خطایی پیش اومد، چه عکس‌العملی نشون بده.

متمرکز بودن اینه که همه‌ی تصمیم‌گیری‌ها، توسط همین Orchestrator انجام می‌شه.

خوب ما اینجا یه سرویس اصلی و مهم داریم که توی روش قبلی نداشتیم : PurchaseOrchestrator
در Choreography بر اساس هر event سرویس ها خودشون میزدن و میرقصیدن ولی اینجا ازین خبرا نیست .

در اینجا PurchaseOrchestrator همه کار هارو پشت سر هم انجام میده و خطا هارو بررسی میکنه و تصمیم میگیره در هر مرحله باید چه اتفاقی بیفته .

اگر مثلاً پرداخت شکست خورد، می‌تونه سفارش رو کنسل کنه یا پیام خطا بده.
در واقع :

  • ترتیب کار سرویس‌ها رو تعیین میکنه
  • بهشون فرمان میده
  • تصمیم‌گیری کنه که در صورت خطا، چی‌کار کنه
  • گردش فرآیند (Workflow) رو مدیریت میکنه


توی Orchestration یه رهبر ارکستر (Orchestrator) هست که می‌گه کی چی بزنه 😄


یه نکته رو یادمون نره Api Gateway و Orchestration کلا ربطی به هم ندارن .
API Gateway یه ورودی واحد (Single Entry Point) برای کل سیستم میکروسرویس‌هاست.

کارهایی که معمولاً انجام می‌ده:

  • احراز هویت و امنیت (Authentication & Authorization)
  • مسیریابی درخواست‌ها (Routing)
  • محدودسازی نرخ درخواست (Rate Limiting)
  • کش کردن (Caching)
  • تبدیل فرمت درخواست و پاسخ (Transformation)
  • نسخه‌بندی API (API Versioning)

این یعنی GateWay بیشتر تمرکز روی مدیریت ورودی داره، نه منطق کسب‌و‌کار یا جریان فرآیندها.

پس Orchestrator چیه؟ ( توی Saga Orchestration)

  • ترتیب کار سرویس‌ها رو تعیین کنه
  • بهشون فرمان بده
  • تصمیم‌گیری کنه که در صورت خطا، چی‌کار کنه
  • گردش فرآیند (Workflow) رو مدیریت کنه

این یعنی Orchestrator روی منطق و کنترل فرآیند متمرکزه.

پس چرا بعضی جاها Gateway به عنوان Orchestrator استفاده می‌شه؟

در بعضی سیناریوهای ساده یا BFF (Backend For Frontend)، ممکنه Gateway:

  • چند درخواست به سرویس‌های مختلف بده
  • نتیجه‌ها رو تجمیع کنه (Aggregation)
  • پاسخ نهایی رو به کلاینت بده

در این حالت‌ها، Gateway یه جور Orchestration سبک (Lightweight) انجام می‌ده، ولی هنوز مثل یه Orchestrator واقعی نیست.



خوب اگر دوس داشتید میتونیم با اسپرینگ بوت و rabbitMQ بیایم یه نمونه پیاده سازی کنیم .

منتظر نگاه های قشنگنتون هستم .


بازم اینو بگم :

توی Choreography سرویس‌ها خودشون "رقص" رو بلدن

ولی توی Orchestration یه رهبر ارکستر (Orchestrator) هست که می‌گه کی چی بزنه 😄