نمط Outbox: جعل الأحداث موثوقة

المشكلة
تحفظ الخدمة طلباً ثم تنشر الحدث order.created. إذا توقفت العملية بين الخطوتين يوجد الطلب دون أن يعلم به أحد. وإذا عكست الترتيب فقد تعلن عن حدث لبيانات لم تُحفظ أصلاً. هذه مشكلة الكتابة المزدوجة (dual write)، ولا تحلها إعادة المحاولة.
النمط
بدلاً من النشر المباشر، اكتب الحدث في جدول Outbox ضمن نفس معاملة قاعدة البيانات التي تحفظ بيانات العمل. إما أن يُحفظ الاثنان معاً أو لا يُحفظ أي منهما. ثم تقرأ عملية منفصلة الصفوف غير المنشورة وتسلّمها وتضع عليها علامة "أُرسل".
- كتابة ذرّية: الحدث موجود إذا وفقط إذا كانت البيانات موجودة.
- تسليم مرة واحدة على الأقل: قد تسلّم العملية الحدث مرتين بعد توقف مفاجئ، لذلك يجب أن يكون المستهلكون idempotent.
- الترتيب: حافظ على الترتيب لكل كيان (مثل رقم الطلب) بدل ترتيب عام.
ما تراقبه في الإنتاج
- تأخر الإرسال: نبّه على عمر أقدم صف غير منشور وليس على الأخطاء فقط.
- الأحداث المعطوبة: حدّد عدد المحاولات ثم اعزل الحدث للفحص بدل أن يعطل الطابور.
- التنظيف: احذف الصفوف المسلّمة أو أرشفها ليبقى الجدول صغيراً.
- التتبع: مرّر معرّف تتبع من الطلب إلى الحدث ثم إلى الـ webhook لتتبع الإجراء الواحد من أوله لآخره.
كيف نستخدمه
Rumuze Core واجهة NestJS مبنية حول هذا النمط: تمر أحداث المجال عبر EventBus إلى Outbox معاملاتي، ومنه إلى محرك Webhooks للتسليم الخارجي وإلى Socket.IO للتوزيع اللحظي عبر Redis. ويجري التحقق من الـ webhooks الواردة قبل قبولها. والفكرة تستحق الاستخدام في أي نظام يعني فيه فقدان حدث فتح بلاغ دعم.
هل أعجبك المقال؟ شاركه مع شبكتك.