مهاجرت جریان پرداخت یکپارچه به معماری رویدادمحور
۲۳ مهر ۱۴۰۴
مسئله و گلوگاههای سیستم سنکرون
در پلتفرمهای پرداخت با هجوم همزمان تراکنشها، پردازش همگام و مونوپلتفرم با مخاطرات جدی پایداری روبرو است:
۱. تایماوتهای زنجیرهای هنگام افزایش بار بانکی: در ساعات پیک ترافیک، تأخیر سوییچهای بانکی شاپرک و درگاههای PSP به بیش از ۵۰۰۰ میلیثانیه میرسید. در معماری همگام، نخهای سرور در انتظار پاسخ بیرونی قفل میماندند و باعث تهیشدن استخر اتصالات (Connection Pool) در کل کلاستر برنامه میشدند. ۲. تراکنشهای شبح و مغایرت مالی: قطعی شبکه پس از کسر موجودی و پیش از ثبت نهایی تاییدیه، منجر به بروز مغایرت در تسویه و تلاشهای مجدد تکراری میشد. ۳. قفلهای سطری روی پایگاه داده: بهروزرسانی مستقیم موجودی حسابها با دستورات جهشپذیر پایگاه داده منجر به بنبست (Deadlock) و کندی شدید پایگاه داده در تراکنشهای همزمان میشد.
رویکرد معماری و پیادهسازی الگوی Outbox
برای قطع وابستگیهای متوالی و صیانت از تراز دقیق مالی، سیستم با ترکیب الگوی Transactional Outbox و ماشین وضعیت تخصیص دومرحلهای بازطراحی شد:
۱. تخصیص دومرحلهای موجودی و دفتر کل دوطرفه
بهجای دستکاری مستقیم ردیفها، جریان حسابداری بر دفتر کل تغییرناپذیر (Append-Only) و ماشین وضعیت دو فاز استوار شد:
- فاز ۱ (رزرو موقت): موجودی از وضعیت AVAILABLE به RESERVED منتقل میشود. این مبلغ بلوکه شده و امکان خرج مضاعف ندارد، اما هنوز از حساب کاربر خارج نشده است.
- فاز ۲ (تعهد نهایی یا آزادسازی): پس از دریافت فراخوانی معتبر از سوییچ تسویه بانکی، مبلغ رزرو شده کسر و به کیف پول مقصد منتقل میشود. در صورت تایماوت یا خطای شبکه، مبلغ دوباره به وضعیت AVAILABLE بازگردانده میشود.
- تراز صفر ریاضی: هر تراکنش حداقل دو رکورد دفتر روزنامه متوازن ایجاد میکند: $$\sum_{i=1}^{n} \text{Debit}i - \sum{j=1}^{m} \text{Credit}_j = 0$$
۲. صفبندی رویدادمحور بر بستر RabbitMQ
- انتشار رویداد از Outbox: تغییرات وضعیت و رویدادهای مالی (activity.event) در قالب یک تراکنش واحد دیتابیس در جدول محلی Outbox ثبت میشوند.
- رهگیری با CDC: سرویس Debezium رکوردهای جدول را بدون خطر نوشتن دوگانه (Dual-Write) به کلاستر صف RabbitMQ هدایت میکند.
- جداسازی صفها: ترافیک در دو مسیر مستقل هدایت میشود: صف activity.pending برای رصد لحظهای و صف activity.end_state برای ثبت نهایی دفاتر مالی.
- تضمین تکرارناپذیری (Idempotency): تمامی مصرفکنندگان پیام موظف به کنترل شناسه یکتای رهگیری (trackingCode) هستند تا دریافت پیامهای تکراری شبکه به اختلال حسابداری نینجامد.
۳. مغایرتگیری دستهای و خودترمیمی
- مغایرتگیری چندمرحلهای شبانه: جاب رصد Spring Batch گزارشهای تسویه بانکی را از طریق سرور امن SFTP دریافت و سطر به سطر با دفاتر مقایسه میکند.
- سرویس بازپرداخت خودکار (Refund-MNG): در صورت تشخیص کسری بدون تسویه، فرآیند برگشت خودکار وجه فعال شده و از مداخله دستی نیروی انسانی جلوگیری میشود.
نتایج عملیاتی در پروداکشن
- پایداری ۹۹.۹۹ درصدی لایه ورودی: جداسازی کامل فرآیندهای لبه از پاسخهای تأخیری شبکه بانکی و عدم قفلشدن منابع سرور.
- مغایرت مالی صفر: حفظ توازن دقیق ریاضی دفتر کل دوطرفه در بیش از ۵۰ هزار رویداد تسویه روزانه.
- همگامی نهایی زیر ۲۰۰ میلیثانیه: کاهش زمان انتشار و نهاییشدن دادهها در سراسر میکروسرویسها به زیر ۲۰۰ میلیثانیه.
- حذف ۹۹.۸ درصدی رفع مغایرت دستی: مدیریت خودکار تراکنشهای ناموفق با موتور مغایرتگیری و خودترمیم.