Cy Logic Insights

تراکنش‌های توزیع‌شده و استراتژی‌های کامیت دو مرحله‌ای در نرم‌افزارهای مالی مبتنی بر میکروسرویس

مدیریت تراکنش‌های توزیع‌شده، ثبات داده‌ها و استراتژی‌های کامیت دو مرحله‌ای را در نرم‌افزارهای مالی که به معماری میکروسرویس منتقل شده‌اند، بررسی می‌کنیم.

تراکنش‌های توزیع‌شده و استراتژی‌های کامیت دو مرحله‌ای در نرم‌افزارهای مالی مبتنی بر میکروسرویس

مقدمه و تحول معماری

با تحول زیرساخت‌های فناوری در کسب‌وکارهای مدرن، گذر از ساختارهای مونولیتیک (یکپارچه) به معماری میکروسرویس سرعت گرفته است. به‌ویژه سیستم‌های مالی و حسابداری و سایر نرم‌افزارهای مالی که فرآیندهای حیاتی عملیاتی را در خود جای داده‌اند، در مرکز این تحول قرار دارند. ساختار سیستم توزیع‌شده در حالی که مقیاس‌پذیری و انعطاف‌پذیری را فراهم می‌کند، چالش‌های فنی پیچیده‌ای را نیز به همراه دارد.

در رأس این چالش‌ها، همگام‌سازی داده‌های تقسیم‌شده میان سرویس‌های مختلف قرار دارد. تضمین‌های ACID (اتمینان، سازگاری، جداسازی، دوام) در سیستم‌های مدیریت پایگاه داده سنتی، هنگامی که صحبت از میکروسرویس‌های مستقل در حال اجرا روی شبکه به میان می‌آید، به‌طور خودکار فراهم نمی‌شوند. این وضعیت، اتخاذ استراتژی‌های جدید در سطح معماری را الزامی می‌کند.

تراکنش‌های توزیع‌شده و چالش‌های ثبات داده‌ها

در دنیای میکروسرویس‌ها، هر سرویس تمایل دارد پایگاه داده خود را داشته باشد. برای مثال، در سناریوهایی که یک تراکنش بدهکار کردن و ثبت وصولی توسط سرویس‌های مختلف پردازش می‌شوند، تاخیرهای شبکه یا قطعی‌های لحظه‌ای اتصال می‌تواند به ناهنجاری‌های جدی منجر شود.

  • وضعیت موفقیت جزئی: در حالی که گام اول یک جریان کاری با موفقیت کامل انجام شده و در پایگاه داده ثبت می‌شود، گام دوم به دلیل خطای شبکه با شکست مواجه می‌شود.
  • مشکلات همزمانی: تضادهای ایجاد شده در نتیجه پردازش درخواست‌های مالی همزمان با ترتیب‌های مختلف در سرویس‌های گوناگون.

در چنین سناریوهایی، ثبات داده‌ها از منظر قابلیت اطمینان سیستم اهمیت حیاتی دارد. از آنجا که مکانیزم‌های قفل‌گذاری (locking) سنتی در محیط‌های توزیع‌شده به گلوگاه‌های عملکردی منجر می‌شوند، باید پروتکل‌های جایگزین مورد ارزیابی قرار گیرند.

پروتکل کامیت دو مرحله‌ای (2PC)

یکی از شناخته‌شده‌ترین رویکردها برای حفظ اتمیسیته (تک‌مرحله‌ای بودن) در تراکنش‌های توزیع‌شده، پروتکل کامیت دو مرحله‌ای (Two-Phase Commit - 2PC) است. این پروتکل تضمین می‌کند که تراکنش توسط تمام سرویس‌های شرکت‌کننده تایید یا به‌طور مشترک لغو شود.

۱. مرحله آماده‌سازی (Prepare Phase)

سرویس هماهنگ‌کننده از تمام سرویس‌های شرکت‌کننده می‌پرسد که آیا آماده انجام تراکنش هستند یا خیر. شرکت‌کنندگان منابع محلی خود را قفل می‌کنند، وضعیت را لاگ کرده و رأی مثبت یا منفی خود را به هماهنگ‌کننده اعلام می‌کنند.

۲. مرحله کامیت (اجرا)

اگر همه شرکت‌کنندگان در مرحله آماده‌سازی پاسخ مثبت داده باشند، هماهنگ‌کننده به همه دستور می‌دهد که تراکنش را نهایی کنند (commit). در صورت دریافت پاسخ منفی از هر یک از شرکت‌کنندگان یا بروز وقفه زمانی (Timeout)، هماهنگ‌کننده دستور لغو تراکنش (rollback) را به تمام سرویس‌ها ابلاغ می‌کند.

رویکردهای جایگزین و تراکنش‌های جبرانی

اگرچه پروتکل کامیت دو مرحله‌ای ثبات قوی را فراهم می‌کند، اما به دلیل مکانیزم‌های قفل‌گذاری سختگیرانه ممکن است عملکرد سیستم را کاهش دهد و در برابر تاخیرهای شبکه آسیب‌پذیر باشد. به همین دلیل، مدل‌های مختلفی نیز برای نرم‌افزارهای مالی مدرن، به‌ویژه آنهایی که حجم تراکنش بالایی دارند، ترجیح داده می‌شوند:

  • الگوی ساگا (Saga Pattern): رویکردی است که تراکنش‌های توزیع‌شده طولانی‌مدت را به یک سری گام‌های محلی تقسیم می‌کند و برای هر گام یک تراکنش جبرانی (compensating transaction) قابل اجرا در جهت معکوس تعریف می‌کند. هنگامی که یک گام با شکست مواجه می‌شود، گام‌های جبرانی رو به عقب به‌ترتیب فعال می‌شوند.
  • ثبات نهایی (Eventual Consistency): به جای قفل‌های لحظه‌ای، با استفاده از معماری‌های رویدادمحور (Event-Driven Architecture) اطمینان حاصل می‌شود که داده‌ها طی یک بازه زمانی مشخص در تمامی سرویس‌ها یکسان شوند.

نتیجه‌گیری

در ساختارهای مالی و حسابداری که به معماری میکروسرویس مهاجرت می‌کنند، مدیریت تراکنش‌های توزیع‌شده و حفظ یکپارچگی داده‌ها نیازمند کار مهندسی دقیقی است. استراتژی‌های کامیت دو مرحله‌ای و مدل‌های جایگزینی مانند ساگا باید با توجه به نیازها و معیارهای عملکردی کسب‌وکارها با دقت انتخاب شوند.

سناریوی نمونه فرضی و جریان کاری

به منظور ملموس کردن این رویکرد معماری تئوریک، یک ماژول مالی را در نظر بگیرید که انتقال پول بین‌المللی و تبدیل نرخ ارز را انجام می‌دهد. هنگامی که کاربر X می‌خواهد بودجه‌ای را از واحد پول محلی به حساب ارزی خود منتقل کند، این درخواست از طریق API Gateway به دو میکروسرویس مستقل هدایت می‌شود: سرویس مدیریت حساب مبدأ و سرویس کیف پول ارز مقصد. با شروع تراکنش، سرویس اصلی که نقش هماهنگ‌کننده را بر عهده دارد، فراخوان آماده‌سازی را به هر دو واحد شرکت‌کننده ارسال می‌کند. در حالی که سرویس مبدأ مسدودسازی موجودی را انجام داده و سیگنال آماده بودن را ارسال می‌کند، سرویس مقصد به دلیل قطعی لحظه‌ای شبکه یا قفل شدن پایگاه داده دچار وقفه زمانی (Timeout) می‌شود. در این حالت، هماهنگ‌کننده مجبور است دستور لغو را به تمام شرکت‌کنندگان ارسال کند. اگر استراتژی‌های قفل‌گذاری کلاسیک بیش از حد طول بکشد، سیستم ممکن است در وضعیت قفل‌شده باقی بماند و موجودی‌های کاربر ناهمسان به نظر برسند. بزرگترین معامله‌پایی (trade-off) که در چنین سناریوهایی با آن مواجه می‌شویم، بین ثبات قوی داده‌ها و دسترسی کلی سیستم (availability) است. مکانیزم‌های قفل سخت‌گیرانه داده‌ها را محافظت کرده اما زمان پاسخ‌دهی را طولانی‌تر می‌کنند؛ مدل‌های منعطف‌تر عملکرد را افزایش داده و خطر تضاد را بالا می‌برند.

چک‌لیست پیاده‌سازی و مدیریت خطا

هنگام راه‌اندازی معماری تراکنش توزیع‌شده در سیستم‌های مالی مبتنی بر میکروسرویس، استانداردهای مهندسی خاصی باید رعایت شوند. نخست، زمان‌های وقفه (timeout) برای سناریوهایی مانند پارتیشن‌بندی شبکه و خرابی هماهنگ‌کننده باید به دقت پیکربندی شوند. در مواردی که سرویس‌های شرکت‌کننده پاسخ نمی‌دهند، مکانیزم‌های جبرانی خودکار باید فعال شوند تا از ماندن سیستم در یک وضعیت نامشخص (in-doubt state) به صورت نامحدود جلوگیری شود. دوم، تمام گام‌های تراکنش توزیع‌شده باید با یک زیرساخت لاگ‌برداری مرکزی و ردیابی توزیع‌شده (distributed tracing) نظارت شوند و اطمینان حاصل شود که هر گام با شناسه‌های تراکنش منحصر به فرد مطابقت دارد. در مرحله مدیریت خطا، سیاست‌های تلاش مجدد با رشد نمایی (exponential backoff) برای قطعی اتصال پایگاه داده و استثناهای بن‌بست (deadlock) باید اعمال شوند. با این حال، به منظور حفظ یکپارچگی داده‌های مالی، نباید از اصول طراحی ایده‌آمپوت (تکرارپذیر) چشم‌پوشی کرد. بدین ترتیب حتی اگر همان درخواست به اشتباه بیش از یک بار فعال شود، موجودی‌ها در معرض پردازش مضاعف قرار نخواهند گرفت.

منابع