الملاحم والمعاملات الموزعة
الملحمة هي معاملة تجارية طويلة الأجل مقسمة إلى سلسلة من الخطوات المحلية عبر مختلف الخدمات/المستودعات. كل خطوة لها إجراء تعويضي يتراجع عن تأثير الخطوة في فشل جزئي. على عكس 2PC/3PC، لا تحتوي القصص على أقفال عالمية وهي مناسبة للخدمات الدقيقة والمتعددة المناطق والأحمال العالية، حيث يكون الاتساق النهائي مقبولاً.
1) متى تختار الملاحم (ومتى لا)
مناسبة:- العمليات التجارية الطويلة/المتعددة الخطوات (طلب الدفع → → الاحتياطي → التسليم).
- مجالات ومستودعات مختلفة لا توجد فيها معاملات مشتركة.
- تحتاج إلى توفر كبير وتوسيع.
- تعتبر ذرية الحمض الصلب أمرًا بالغ الأهمية (على سبيل المثال، تحويل كميات كبيرة داخل نفس السجل).
- لا توجد قابلية واضحة للتعويض (لا يمكنك «الاحتفاظ» أو إلغاء التأثير).
- تتطلب القيود القانونية/التنظيمية عزلة صارمة وثابتة «فورية».
2) نماذج Sagas
1. Saga Orchestrator - المنسق المركزي يدير الخطوات والتعويضات.
الإيجابيات: التدفق الصريح، التحكم في الخطأ، القياس عن بعد المبسط.
السلبيات: نقطة المركزية، خطر المنسق «السمين».
2. تصميم الرقصات (Choreography): لا يوجد مركز - تبدأ الخطوات بالأحداث («الخدمة أ هل تتفاعل X → service B»).
الإيجابيات: اتصال ضعيف، تحجيم بسيط.
السلبيات: من الصعب تتبع/تصحيح التدفق، وخطر «امتداد» القواعد.
3. TCC (حاول التأكيد/الإلغاء) - كل خطوة هي «جرب»، ثم تأكيد أو إلغاء.
الإيجابيات: أقرب إلى بروتوكول مرحلتين زائف، الموارد المدارة.
السلبيات: أكثر تكلفة في تنفيذ الوصلات البينية ؛ يتطلب «جرب» مهلة حامل.
3) تصميم الملعب والتعويض
الثوابت: تذكر بوضوح ما يجب أن يكون صحيحًا «قبل/بعد» الخطوة (على سبيل المثال، «الباقي ≥ 0»).
التعويض ≠ المعاملة العكسية: هذا إجراء منطقي يلغي الأثر التجاري (الاسترداد، الإفراج، الاستعادة).
الاختصاص: يجب أن يتكرر كل من الخطوة والمعوض بأمان (عن طريق 'التشغيل _ id').
المهلة: لكل خطوة موعد نهائي ؛ ويؤدي التأخير إلى دفع تعويض.
آثار عدم الإعادة: تسجيلها بشكل منفصل (الإخطارات، البريد الإلكتروني) والسماح «بأفضل جهد».
4) الاتساق والنظام
الاتساق في نهاية المطاف: يمكن للمستخدمين رؤية التباينات الزمنية ؛ UX - مع «الانتظار «/المغازل/الحالات.
اطلب حسب المفتاح - قم بتجميع خطوات التبديل حسب مفتاح العمل (order_id) لطلب الأحداث.
Deduplication - تخزين سجل المعالجة ('التشغيل _ id' حالة →) مع TTL.
5) النقل والموثوقية
يكتب نمط Outbox الحدث إلى جدول outbox المحلي ضمن نفس المعاملة، ثم ينشره بشكل غير متزامن إلى الحافلة.
متجر Inbox/Idempotency: من جانب المستهلك - تم معالجة سجل الرسائل بالفعل.
مرة واحدة بالضبط بشكل فعال: «outbox + المستهلك الخفي» يعطي عمليًا «مرة واحدة بالضبط».
DLQ: للرسائل «السامة» مع المعلومات الفوقية الغنية وإعادة التوليد الآمن.
6) سياسات الخطأ، إعادة الدرس، التراجع
إننا لا نكرر سوى الخطوات الحمقاء ؛ اكتب العمليات - مع «Idempotency-Key».
التراجع الأسي + الجتر ؛ الحد من المحاولات والموعد النهائي الموجز للملحمة.
مع التدهور المنهجي - قاطع الدائرة والتحلل الرشيق (على سبيل المثال، إلغاء جزء الخيال الثانوي من الملحمة).
النزاعات التجارية ('409') - إعادة المحاكمة بعد المصالحة أو التعويض وإنهائها.
7) المنسق: المسؤوليات والهيكل
الوظائف:- تتبع حالة الملحمة: «→ المعلقة الجارية → تعويض → المنجزة/الفاشلة».
- خطوات التخطيط، المواعيد النهائية، المهلات، التراجعات.
- إطلاق توجيه الحدث والتعويض.
- فراغ عمليات المنسقين (سجل القيادة).
- إمكانية الملاحظة: ارتباط 'saga _ id' في السجلات/الآثار/المقاييس.
- الجداول «ملحمة»، «ملحمة _ خطوة»، «أوامر»، «outbox».
- الفهارس على «saga _ id»، «business _ key»، «status'،» next _ run _ at'.
8) تصميم الرقصات: القواعد والحماية من «كرة الثلج»
عقود الأحداث: المخططات والتحرير (Avro/Proto/JSON Schema).
دلالات واضحة: «حقيقة الحدث» مقابل «الأمر».
إيقاف السلسلة: بعد أن اكتشفت الخدمة عدم تطابق، تنشر حدث «فاشل »/« تعويض».
الإنذارات والتنبيهات على «حلقات لا نهاية لها».
9) التعاون التقني: تفاصيل عملية
جرب: احتياطي الموارد مع TTL.
تأكيد: الالتزام، تحرير الأقفال المؤقتة.
إلغاء: التراجع الاحتياطي (بدون آثار جانبية).
جمع القمامة: الإلغاء التلقائي لـ Try after TTL (إلغاء idempotent).
تأكيد/إلغاء الخصوصية: التكرار آمن.
10) مثال (مخطط الكلمات) - «طلب مع الدفع والتسليم»
1. CreateOrder (محلي) → outbox: «OrderCreated».
2. خدمة الدفع: احتياطي «جرب» (TCC) ؛ إذا → «الدفع المحجوز»، إذا فشلت → «الدفع».
3. خدمة الجرد: احتياطي المنتجات ؛ من → «فشل الجرد».
4. ShippingService - إنشاء فتحة تسليم (قابلة للإلغاء).
5. إذا كانت هناك أي خطوة «فاشلة» → يبدأ المنسق التعويضات بالترتيب العكسي: «إلغاء الشحن» → «تحرير المخزون» → «إلغاء الدفع».
6. إذا كان كل شيء على ما يرام → «تأكيد الدفع» → «تأكيد الطلب».
11) أوركستراتور كاذب
pseudo startSaga(saga_id, order_id):
steps = [ReservePayment, ReserveInventory, BookShipment, ConfirmPayment]
for step in steps:
res = execWithRetry(step, order_id)
if!res.ok:
compensateInReverse(steps_done(order_id))
return FAIL return OK
execWithRetry(step, key):
for attempt in 1..MAX:
try:
return step.run(key) # идемпотентно catch RetryableError:
sleep(backoff(attempt))
catch NonRetryableError:
return FAIL return FAIL
compensateInReverse(done_steps):
for step in reverse(done_steps):
step.compensate() # идемпотентно
12) قابلية الملاحظة وتشغيل SLOs
التعقب: 'ملحمة _ هوية' واحدة، شروح 'خطوة'، 'محاولة'، 'قرار' (تشغيل/تعويض/تخطي).
المقاييس:- نجاح/خطأ الملحمة (%)، متوسط المدة، p95/p99.
- حصة الملاحم التعويضية، أهم أسباب التعويض.
- قوائم الانتظار/تأخيرات outbox، إعادة الدرج في الخطوات.
- السجلات/عمليات التدقيق: حلول المنسق، ومحددات الموارد، ومفاتيح العمل.
13) الاختبار والفوضى
حقن الأخطاء في كل خطوة: المهلة، «5xx»، النزاعات التجارية.
أحداث خارجة عن النظام، مكررة، تسقط.
ذيول طويلة من زمن الوصول → التحقق من المواعيد النهائية والتعويضات.
الملاحم الجماعية → التحقق من WFQ/DRR والقبعات في قوائم الانتظار، وغياب «حجب رأس الخط».
أعد السحب من DLQ في خطوات وفي ملحمة كاملة.
14) تعدد الإيجارات والمناطق والامتثال
مستأجر العلامات _ معرف/خطة/منطقة في الأحداث ومستودعات الملحمة.
الإقامة: لا تغادر البيانات/الأحداث المنطقة ؛ تم تصميم القصص عبر الإقليمية على أنها اتحادات للملاحم المحلية + الأحداث التجميعية.
تحديد الأولويات: تحمل قصص كبار الشخصيات وزناً أكبر للحصص ؛ لكل مستأجر.
15) قائمة مرجعية قبل البيع
- لكل خطوة تعويض واضح، وكلاهما خفي.
- النموذج المختار: التنسيق/تصميم الرقصات/خدمات الدعم التقني ؛ ويرد وصف لحدود المسؤولية.
- Outbox/Inbox المنفذ، التفريغ بواسطة 'operation _ id'.
- سياسات إعادة التدوير: التراجع مع التنفس، وتجربة الحدود والموعد النهائي العام للملحمة.
- يتم التحقق من عقود الأحداث، وهناك التحقق من صحة المخطط.
- تم تكوين DLQ والإصدار الآمن.
- القياس عن بعد: المقاييس، والتعقب، والارتباط 'saga _ id'.
- كتب اللعب التشغيلية: إلغاء يدوي/تأكيد قسري، فتح ملحمات «معلقة».
- تمرير الفوضى واختبارات التحميل، ميزانية SLO/خطأ محدد.
16) أخطاء نموذجية
لا يوجد تعويض أو أنه «نجس» (له آثار جانبية).
لا يوجد إفراط/تخلص - زوجي و «تقلبات» في الدول.
«Saga in Saga» بدون حدود صريحة - دورات وأقفال متبادلة.
لا توجد مواعيد نهائية → قصص «أبدية» وتسريبات للموارد.
يقوم المنسق بتخزين الدولة «في الذاكرة» بدون متجر مستقر.
تصميم الرقصات بدون مركز قياس عن بعد → إخفاقات «غير مرئية».
UX غير الشفاف: لا يرى المستخدمون حالات وسيطة.
17) وصفات سريعة
كلاسيكيات SaaS: التنسيق + outbox/inbox، التراجع الأسي، DLQ، حالات الملحمة في واجهة المستخدم.
ثوابت الموارد القوية: TCC مع احتياطي TTL و GC إلغاء.
الحجم الكبير/الحمل: تصميم رقصات الحدث + الخصوصية الصارمة والمقاييس الرئيسية.
متعدد المناطق: الملاحم المحلية + المجاميع النهائية ؛ تجنب الأقفال العالمية.
خامسا - الاستنتاج
تعتبر Sagas طريقة للحصول على اتساق يمكن التنبؤ به في الأنظمة الموزعة بدون أقفال عالمية. إن التعويضات الواضحة، والخصوصية، والتسليم الموثوق (outbox/inbox)، والاستبعاد وإعادة الدفع، بالإضافة إلى القياس عن بعد وكتب اللعب هي المفتاح لضمان بقاء العمليات التجارية المعقدة مستقرة وقابلة للقراءة مع زيادة العبء وعدد الخدمات والمناطق الجغرافية.