منصة تسليم الأحداث — Webhooks موثوقة
مشروع ذاتي لتطبيق أنماط الموثوقية في أنظمة الإنتاج — Outbox ومفاتيح Idempotency وقاطع الدائرة — على خدمة Spring Boot لتسليم الأحداث.
- دوري
- مطوّر منفرد · مشروع ذاتي
- التقنيات
- Java / Spring Boot / Spring Security / Flyway / Resilience4j
شكل ٠١ التسليم الموثوق للأحداث
- 2 نوعا رموز JWT — وصول قصير العمر، وتحديث منفصل
- 3 حالات قاطع الدائرة — مغلق، مفتوح، نصف مفتوح
- Flyway هجرات قاعدة بيانات مُرقّمة وقابلة لإعادة البناء
محاكاة للتصميم المستهدف — بعض أجزائه قيد التطوير، والقيم المعروضة ليست قياسات. اقرأ الرسم
- الخدمة: تحفظ السجل وحدث الإرسال في المعاملة نفسها (Transactional Outbox)، فلا يُكتب أحدهما دون الآخر.
- جدول Outbox: الأحداث تنتظر هنا حتى تُسلَّم — لا تضيع إن سقطت الخدمة أو تعطّل المستقبِل.
- المُرسِل: يسحب الأحداث المعلّقة ويرسلها مع مفتاح Idempotency، فيتجاهل المستقبِل أي تكرار.
- قاطع الدائرة (Resilience4j): بعد فشل متكرر يفتح ويوقف الإرسال مؤقتًا، ثم يجرّب طلبًا واحدًا (نصف مفتوح) قبل أن يُغلق من جديد.
- المستقبِل: نقطة الـ webhook لدى العميل. عطّلها من الزر أدناه وراقب ما يحدث.
المشكلة
حين يعتمد نظام على إرسال أحداث إلى أنظمة أخرى عبر webhooks، يصبح السؤال الحقيقي: ماذا يحدث إذا سقطت الخدمة بعد حفظ البيانات وقبل الإرسال؟ أو إذا تعطّل المستقبِل ساعة كاملة؟ الإرسال المباشر من داخل الطلب يعني في النهاية أحداثًا ضائعة أو مكررة.
دوري
مشروع ذاتي أبنيه وحدي لتطبيق أنماط الموثوقية المستخدمة في أنظمة الإنتاج، من تصميم قاعدة البيانات إلى طبقة الأمان.
القرارات
- مصادقة بالرموز: JWT عبر Spring Security، مع فصل رمز الوصول عن رمز التحديث.
- هجرات مُرقّمة: مخطط قاعدة البيانات يُدار عبر Flyway، فيبقى قابلًا للتتبع وإعادة البناء في أي بيئة.
- Transactional Outbox: يُكتب الحدث في المعاملة نفسها مع السجل، ثم يُرسل لاحقًا — فلا حدث دون سجل، ولا سجل دون حدث.
- مفاتيح Idempotency: تجعل إعادة الإرسال آمنة، فالمستقبِل يتجاهل ما وصله من قبل.
- قاطع الدائرة وتحديد المعدّل: عبر Resilience4j، لحماية المستقبِل المتعثّر من سيل محاولات متتالية.
ما يمكن إثباته
المكتمل حتى الآن: المصادقة بالرموز المنفصلة والهجرات المُرقّمة. أما Outbox ومفاتيح Idempotency وقاطع الدائرة وتحديد المعدّل فقيد التطوير — والرسم أعلاه يوضّح التصميم المستهدف، لا نسخة منشورة.
الحدود والدروس
لا أدّعي هنا أرقام أداء أو مستخدمين؛ المشروع مساحة لتطبيق أنماط أتعامل معها في العمل. القرار الذي أدافع عنه هو فصل «حفظ الحدث» عن «إرساله»: هو ما يجعل كل نمط بعده — الإعادة، والقاطع، وتحديد المعدّل — ممكنًا دون خوف من فقدان البيانات.