نمط الملحمة والمعاملات الموزعة
نمط الملحمة والمعاملات الموزعة
1) لماذا هناك حاجة إلى القصص
2PC الكلاسيكية (الإمساك بمرحلتين) قابلة للتطوير بشكل سيئ ومعقدة في ظل الإخفاقات وحظر الموارد. تقسم الملحمة عملية العمل الشاملة إلى سلسلة من المعاملات المحلية (الخطوات)، والتي تلتزم كل منها بشكل مستقل. في حالة الفشل، يتم إلغاء الخطوات اللاحقة، ويتم تعويض الخطوات التي تم الانتهاء منها بالفعل عن طريق العمليات العكسية.
النتيجة: الاتساق المُدار في نهاية المطاف دون حظر عالمي، وقدرة عالية على البقاء وبروتوكول استرداد واضح.
2) النماذج الأساسية
2. 1 التنسيق
يقوم منسق ملحمة مخصص بإدارة الخطوات: يرسل الأوامر، وينتظر الردود/الأحداث، ويبدأ التعويضات.
الإيجابيات: التحكم المركزي، والمراقبة البسيطة، والمواعيد النهائية الصريحة. السلبيات: مكون اختياري.
2. 2 تصميم الرقصات
لا يوجد منسق ؛ تستجيب الخدمات لأحداث بعضها البعض («OrderPlated» → «PaymentCatured» → «InventoryReserved»...).
الإيجابيات: ضعف الاتصال. السلبيات: يصعب تتبع خطر «رقصة الموت» بدون قواعد واضحة.
2. 3 TCC (حاول التأكيد/الإلغاء)
خيار بموارد «التجميد»:1. جرب - التحضير/الاحتياطي،
2. تأكيد - تثبيت،
3. إلغاء - التراجع.
الضمانات أعلى، لكن العقود والمهل الزمنية الاحتياطية أكثر تعقيدًا.
3) عقود الخطوة والتعويض
كل خطوة = معاملة محلية + تعويض (خفي، يسمح بالتكرار).
ولا يشترط التعويض «لإعادة العالم» بالكامل - فمكافئ الحقل كاف (على سبيل المثال، «دفع العائد» بدلا من «حذف الدفع»).
تعريف الثوابت: بالنسبة للمال - الرصيد لا يذهب إلى ناقص ؛ للأوامر - لا وضع «معلق».
أدخل المواعيد النهائية/احتياطيات TTL و «جامع القمامة» للمحاولات المتأخرة.
4) دلالات الاتساق والتسليم
إيصال الرسالة: يجب أن تكون جميع العمليات → مرة واحدة على الأقل (افتراضية)، خفية.
الترتيب: مهم حسب مفتاح الارتباط (على سبيل المثال 'order _ id', 'player _ id').
مرة واحدة بالضبط ليس هدف الملحمة ؛ نحقق التوحيد الفعال من خلال المفاتيح الخفية والصندوق الخارجي/البريد الوارد والالتزام الصحيح.
5) حالة الملحمة وسجلها
ماذا تخزن:- 'saga _ id'، 'correnation _ id'، الوضع الحالي (تشغيل/اكتمال/تعويض/تعويض/فشل)،
- الخطوة ومتغيراتها (بطاقات الدفع/الاحتياطي)،
- تاريخ (سجل) الأحداث/القرارات، والطوابع الزمنية، والمواعيد النهائية، وعدد عمليات إعادة التدوير.
- متجر Saga منفصل (جدول/وثيقة) متاح للمنسق.
- لتصميم الرقصات - «وكلاء» محليون للملحمة، ونشر أحداث الحالة في موضوع مشترك.
6) أنماط نشر موثوقة: outbox/inbox
Outbox: تلتزم الخطوة بالتغيير وتكتب الحدث/الأمر إلى جدول outbox في معاملة واحدة ؛ ينشر العامل في الإطار.
Inbox: يحتفظ المستهلك بجدول «message _ id» المعالج → dedup + idempotency.
بعد تأثير جانبي ناجح، قم بالتعويض/ACK (Kafka/RabbitMQ) - ليس قبل ذلك.
7) تصميم خطوات الملحمة
7. 1 مثال (شراء iGaming/التجارة الإلكترونية)
1. PlaceOrder → status 'About'.
2. إذن الدفع (جرب) → «الدفع _ عقد _ معرف».
3. ReserveInstruction → 'reservation _ id'.
4. التقاط الدفع (تأكيد).
5. أنهي الأمر → «اكتمل».
- (3) إذا فشل → «إلغاء الدفع» ؛
- (4) فشل بعد (3) → «حصر الإصدار» ؛
- (5) إذا فشل → «الدفع المسترد» و «مخزون الإصدار».
7. 2 المواعيد النهائية/المعتكفات
يعيد الحد الأقصى N مع تأخير أسي + نفث.
بعد تجاوز - انتقل إلى «التعويض».
تخزين next_attempt_at deadline_at لكل خطوة.
8) المنسق مقابل المنصة
الخيارات:- منسق منزلي خفيف الوزن (microservice + table Saga).
- المنصات: Temporal/Cadence و Camunda و Netflix Conductor و Zeebe - امنح أجهزة توقيت واسترجاع وتدفقات عمل طويلة الأمد ورؤية ووحدة تحكم على الويب.
- لتصميم الرقصات، استخدم كتالوج الأحداث وحالة/اتفاقية رئيسية صارمة.
9) بروتوكولات التكامل
9. 1 غير متزامن (كافكا/RabbitMQ)
الأوامر: المدفوعات. يأذن. v1 '،' المخزون. الاحتياطي. v1 '.
الأحداث: المدفوعات. المأذون به. v1 '،' المخزون. محجوز v1 '،' المدفوعات. تم القبض عليه. v1 '،' المدفوعات. المستردة. v1 '.
مفتاح الجزء = 'طلب _ معرف '/' مشغل _ معرف' للطلب.
9. 2 متزامن (HTTP/gRPC) ضمن خطوة
يصلح للخطوات «القصيرة»، ولكن دائمًا مع المهلات/الاسترجاع/الخصوصية والعودة إلى التعويض غير المتزامن.
10) الفراغ والمفاتيح
في طلبات القيادة والتعويض، مرر «الخصوصية _ المفتاح».
يتم تنفيذ الآثار الجانبية (الكتابة إلى قاعدة البيانات/الشطب) بشكل مشروط: «الأداء إذا لم تكن قد رأيت بعد» الخصوصية _ المفتاح «».
التعويضات هي أيضًا خفية: تكرار «استرداد الدفع (معرف = X)» آمن.
11) معالجة الأخطاء
الفصول:- Transient (networks/timeouts) → retray/backoff.
- الأعمال (عدم كفاية الأموال والحدود) → التعويض الفوري/المسار البديل.
- تدخل يدوي → غير قابل للاسترداد، تعويض يدوي.
- بناء مصفوفة حل: نوع خطأ → إجراء (إعادة/تعويض/تصعيد).
12) إمكانية الرصد و sag SLO
SLI/SLO:- الكمون من البداية إلى النهاية للملحمة (p50/p95/p99).
- معدل النجاح.
- يعني الوقت للتعويض и معدل التعويض.
- القصص اليتيمة والوقت إلى GC.
- يتتبع: 'trace _ id '/' saga _ id' كحلقة وصل بين الخطوات ؛ مقاييس معدل الحرق لميزانيات الأخطاء.
السجلات: كل تغير في حالة الملحمة = سجل منظم مع السبب.
13) أمثلة (كاذب)
13. 1 منسق (فكرة)
python def handle(OrderPlaced e):
saga = Saga. start(e. order_id)
saga. run(step=authorize_payment, compensate=cancel_payment)
saga. run(step=reserve_inventory, compensate=release_inventory)
saga. run(step=capture_payment, compensate=refund_payment)
saga. run(step=finalize_order, compensate=refund_and_release)
saga. complete()
def run(step, compensate):
try:
step () # local transaction + outbox except Transient:
schedule_retry()
except Business as err:
start_compensation(err)
13. 2 Outbox (فكرة الجدول)
outbox(id PK, aggregate_id, event_type, payload, created_at, sent_at NULL)
inbox(message_id PK, processed_at, status)
saga(order_id PK, state, step, next_attempt_at, deadline_at, context JSONB)
saga_log(id PK, order_id, time, event, details)
13. 3 تصميم الرقصات (أفكار موضوعية)
أوامر. وضع «المستهلكين →: » المدفوعات. يأذن «،» المخزون. احتياطي "
المدفوعات. مخزون '+' المأذون به. الأوامر «→» المحفوظة. try_finalize'
أي فشل في أوامر →. تعويض المدفوعات '→ بدأت'. إلغاء/استرداد '،' المخزون. الإفراج '.
14) المقارنة مع 2PC و ES
2PC: اتساق قوي، لكن انسداد، اختناقات، أنابيب نحاسية.
الملحمة: الاتساق النهائي، تحتاج إلى نظام للتعويض والقياس عن بُعد.
تحديد مصادر الأحداث: تخزين الأحداث كمصدر للحقيقة ؛ القصص عليها طبيعية، لكنها تضيف تعقيدًا إلى الهجرات/اللقطات.
15) السلامة والامتثال
أمن النقل (TLS/mTLS)، ACL لكل موضوع/قائمة انتظار.
في الأحداث - على الأقل PII، تشفير الحقول الحساسة، الترميز.
الوصول إلى الملاحم وسجلات التعويضات.
SLA مع مقدمي الخدمات الخارجيين (المدفوعات/التسليم) = الموعد النهائي وبارامترات حدود إعادة الدفع.
16) قائمة التنفيذ المرجعية (0-45 يوما)
0-10 أيام
اختر عمليات المرشحين (متعددة الخدمات، تعويض).
حدد النموذج (التنسيق/تصميم الرقصات/TCC) ومفتاح الارتباط.
وصف الخطوات/التعويضات والثوابت والمواعيد النهائية. ارفع الطاولات «ملحمة» و «outbox» و «inbox».
11-25 يومًا
قم بتضمين outbox/inbox و idempotency و retractes التراجع.
استنفد القصة الأولى ؛ إضافة لوحات معلومات وتعقب SLI/SLO.
اكتب دليلًا للتعويضات (بما في ذلك الدليل) والتصعيد.
26-45 يومًا
أتمتة ملحمات GC «المعلقة»، إعادة التشغيل/الاستمرارية الدورية في الموعد النهائي.
قضاء يوم اللعبة: فشل الخطوة، زيادة الموعد النهائي، عدم توفر الوسيط.
توحيد عقود الأحداث (الإصدارات، التوافق)، إعداد «دليل ملحمة».
17) الأنماط المضادة
«التعويض = تحذف من قاعدة البيانات» بدلا من الإجراء العكسي الصحيح.
لا يوجد صندوق خارجي/صندوق بريد → فقدان الأحداث/التأثيرات المزدوجة.
Retrai without jitter → self-DDoS.
توقع اتساق قوي في القراءة دون «المعالجة جارية»....
منسق عملاق واحد لجميع → التحكم المتراصة.
تصميم الرقصات الكامل بدون رؤية و SLA → رقصة لا يمكن السيطرة عليها.
تجاهل المواعيد النهائية → الاحتياطيات/المعلقة الأبدية.
18) مقاييس النضج
≥ 90٪ من العمليات الحرجة مشمولة بالملاحم/التعويضات ولديها الثوابت الموصوفة.
تم دمج Outbox/inbox لجميع المنتجين/المستهلكين Tier-0/1.
SLO: ملحمة p95 من طرف إلى طرف طبيعية، معدل النجاح مستقر، يتيم <الهدف.
تتبع شفاف ولوحات القيادة «في خطوات» تنبيهات معدل الحرق.
فحص تعويض يوم اللعبة ربع السنوي ودليل التشغيل اليدوي.
19)
Saga هو عقد عملي للتماسك للأنظمة الموزعة: خطوات واضحة وإجراءات عكسية، ونشر الانضباط (outbox/inbox)، والمواعيد النهائية وعمليات إعادة التدوير، وإمكانية الملاحظة، وعمليات التعويض. اختر نموذجًا (التنسيق/تصميم الرقصات/TSS)، وأصلح الثوابت والمفاتيح، واجعل المعالجات خفية - وستصبح عمليات العمل متعددة الخدمات الخاصة بك قابلة للتنبؤ ومستقرة دون 2PC باهظة الثمن.