التطور من التطبيق المتجانب إلى الخدمات المصغرة
مقدمة
لا توجد بنية "الأفضل"، بل فقط "الأكثر ملاءمة للمرحلة الحالية". الانتقال من التطبيق المتجانب إلى الخدمات المصغرة ليس قفزة تتم دفعة واحدة، بل عملية تطورية تدريجية مع نمو حجم العمل والفريق. التقسيم المبكر للخدمات المصغرة بنفس خطورة التقسيم المتأخر.
ماذا ستتعلم من هذه المقالة؟
بعد إتمام هذا الفصل، ستكتسب:
- مسار التطور: فهم المراحل الأربع من التطبيق المتجانب إلى الخدمات المصغرة
- توقيت التقسيم: معرفة متى يجب التقسيم ومتى يجب عدم التقسيم
- استراتيجيات التقسيم: إتقان منهجية التقسيم حسب النطاق التجاري
- أنماط الاتصال: التعرف على خيارات الاتصال المتزامن وغير المتزامن بين الخدمات
- تقسيم البيانات: فهم تحديات وحلول تقسيم قواعد البيانات
| الفصل | المحتوى | المفاهيم الأساسية |
|---|---|---|
| الفصل 1 | مسار التطور البنيوي | متجانب ← وحدات ← SOA ← خدمات مصغرة |
| الفصل 2 | توقيت ومبادئ التقسيم | قانون كونواي، استقلالية الفريق |
| الفصل 3 | استراتيجيات التقسيم | سياق محدد في DDD، نمط الكُرسُن الخانق |
| الفصل 4 | اتصال الخدمات | REST، gRPC، قوائم انتظار الرسائل |
| الفصل 5 | تقسيم البيانات | تقسيم قواعد البيانات، مزامنة البيانات |
1. مسار التطور البنيوي
التطور البنيوي لا تقوده التكنولوجيا، بل حجم المنظمة. عندما ينمو الفريق من 5 أشخاص إلى 500، تنخفض كفاءة التعاون في البنية المتجانبة بشكل حاد.
| المرحلة | البنية | حجم الفريق | الخصائص |
|---|---|---|---|
| البداية | تطبيق متجانب | 1~10 أشخاص | جميع الشيفرة في مشروع واحد، نشر بسيط |
| النمو | متجانب وحدات | 10~50 شخصًا | الشيفرة مقسمة لوحدات لكن تُنشر معًا |
| التوسع | SOA (الخدماتية) | 50~200 شخص | تقسيم حسب خطوط العمل لخدمات ذات حبيبية خشنة |
| الحجم الكبير | خدمات مصغرة | 200+ شخص | خدمات ذات حبيبية دقيقة، كل فريق يطور ويَنشر بشكل مستقل |
قانون كونواي
"المنظمات التي تصمم الأنظمة... تُنتج بنى تعادل هياكل الاتصال في تلك المنظمات." — ملفين كونواي
ببساطة: 3 فرق تصنع نظامًا، سينتهي الأمر بـ 3 خدمات. جوهر التقسيم البنيوي هو التقسيم التنظيمي.
قانون كونواي العكسي: بما أن الهيكل التنظيمي يُحدد بنية النظام، إذا أردت بنية معينة، فعدّل هيمنك التنظيمي أولًا. مثلًا إذا أردت خدمة دفع مستقلة، فأنشئ فريق دفع مستقل أولًا. فشل تقسيم الخدمات المصغرة في العديد من الشركات ليس مشكلة تقنية، بل لأن المنظمة لم تتكيف.
2. متى يجب تقسيم الخدمات المصغرة؟
ليست كل الأنظمة تحتاج خدمات مصغرة. التقسيم المبكر يجلب تعقيدًا غير ضروري.
| الإشارة | الشرح | التوصية |
|---|---|---|
| تكرار تعارضات النشر | عدة فرق تعدل نفس قاعدة الشيفرة، وتتعارض باستمرار | فكر في التقسيم |
| وحدة تحتاج توسعًا مستقلًا | وحدة البحث تحتاج 10 أضعاف موارد الوحدات الأخرى | فكر في التقسيم |
| الحاجة لتنويع حزمة التقنيات | وحدة الذكاء الاصطناعي تستخدم Python، والموقع الرئيسي Java | فكر في التقسيم |
| الفريق أقل من 10 أشخاص | تكلفة التواصل منخفضة، والمتججانب كافٍ | لا تقسّم |
| العمل لا يزال في مرحلة الاستكشاف | المتطلبات تتغير بسرعة، والحدود غير واضحة | لا تقسّم |
| لا توجد قدرات DevOps | لا يوجد CI/CD، أو حاويات، أو نظام مراقبة | لا تقسّم |
3. استراتيجيات التقسيم
3.1 التقسيم حسب النطاق التجاري (السياق المحدد في DDD)
السياق المحدد (Bounded Context) في DDD (التصميم الموجه بالمجال) هو أفضل مبدأ توجيهي لتقسيم الخدمات المصغرة. كل سياق محدد يقابل نطاقًا تجاريًا مستقلًا، بنموذج بيانات وقواعد عمل خاصة به.
ما هو السياق المحدد؟ نفس الكلمة لها معانٍ مختلفة في نطاقات تجارية مختلفة. مثلًا "المستخدم" في نطاق المستخدمين يعني معلومات التسجيل (الاسم، البريد الإلكتروني)، وفي نطاق الطلبات يعني الطالب (عنوان الشحن، طريقة الدفع)، وفي نطاق التوصيات يعني السلوك (سجل التصفح، علامات التفضيل). السياق المحدد يرسم حدودًا داخلها تكون المصطلحات والنماذج ذات معنى واضح وموحد.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ نطاق المستخدمين │ │ نطاق الطلبات │ │ نطاق الدفع │
│ │ │ │ │ │
│ User │ │ Order │ │ Payment │
│ Profile │ │ OrderItem │ │ Refund │
│ Address │ │ Cart │ │ Transaction │
│ │ │ │ │ │
│ خدمة المستخدمين │ │ خدمة الطلبات │ │ خدمة الدفع │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└────── استدعاء API / اتصال بالأحداث ───────┘| السياق المحدد | الكيانات الأساسية | الخدمة المقابلة |
|---|---|---|
| نطاق المستخدمين | User، Profile، Address | خدمة المستخدمين |
| نطاق المنتجات | Product، Category، SKU | خدمة المنتجات |
| نطاق الطلبات | Order، OrderItem | خدمة الطلبات |
| نطاق الدفع | Payment، Refund | خدمة الدفع |
| نطاق الشحن | Shipment، Tracking | خدمة الشحن |
3.2 نمط الكُرسُن الخانق (Strangler Fig Pattern)
لا تُعد كتابة التطبيق المتجانب بالكامل دفعة واحدة، بل كالكُرسُن الخانق: استبدل الوحدات القديمة تدريجيًا بخدمات جديدة:
- أنشئ خدمة جديدة خارج التطبيق المتجانب
- وجّه جزءًا من الزيارات إلى الخدمة الجديدة عبر طبقة وكيل
- بعد التأكد من استقرار الخدمة الجديدة، انقل المزيد من الزيارات تدريجيًا
- استبدل الوحدة القديمة بالكامل في النهاية
4. أنماط اتصال الخدمات
| الطريقة | البروتوكول | الخصائص | السيناريو المناسب |
|---|---|---|---|
| REST | HTTP/JSON | بسيط وعام، بيئة غنية | واجهات API الخارجية، عمليات CRUD |
| gRPC | HTTP/2 + Protobuf | أداء عالٍ، أنواع قوية | الاستدعاءات المتكررة بين الخدمات الداخلية |
| قوائم انتظار الرسائل | AMQP/Kafka | فصل غير متزامن، تسوية الذروة | إشعارات الأحداث، المهام غير المتزامنة |
| GraphQL | HTTP/JSON | استعلام حسب الحاجة من جانب العميل | طبقة BFF، تطبيقات الجوال |
الاختيار بين المتزامن وغير المتزامن
- تحتاج نتيجة فورية ← متزامن (REST/gRPC)
- لا تحتاج نتيجة فورية ← غير متزامن (قائمة انتظار الرسائل)
- حدث واحد يُفعّل عدة إجراءات ← غير متزامن (نشر-اشتراك)
القاعدة العامة: استخدم غير المتزامن حيثما أمكن، فكلما طالت سلسلة الاستدعاءات المتزامنة، أصبح النظام أكثر هشاشة.
5. تقسيم البيانات: الجزء الأصعب
الألم الأكبر في تقسيم الخدمات المصغرة ليس تقسيم الشيفرة، بل تقسيم قواعد البيانات. يجب أن تمتلك كل خدمة قاعدة بياناتها الخاصة، لكن هذا يعني أن الاستعلامات عبر الخدمات تصبح صعبة.
| التحدي | الوصف | الحل |
|---|---|---|
| JOIN عبر الخدمات | لا يمكن عمل JOIN مباشر لجداول خدمتين | استعلام مركب عبر API، تكرار البيانات |
| المعاملات الموزعة | المعاملات عبر قواعد البيانات لا يمكن استخدام المعاملات المحلية | Saga، جدول الرسائل المحلي |
| تناسق البيانات | بيانات عدة خدمات قد تكون غير متسقة مؤقتًا | التناسق النهائي، الأحداث |
| نقل البيانات | من قاعدة مشتركة إلى قاعدة مستقلة | فترة كتابة مزدوجة، أدوات مزامنة البيانات |
الخلاصة
الانتقال من التطبيق المتجانب إلى الخدمات المصغرة عملية تدريجية، وليس ثورة تتم دفعة واحدة.
نراجع النقاط الرئيسية في هذا الفصل:
- مسار التطور: متجانب ← متجانب وحدات ← SOA ← خدمات مصغرة، لكل خطوة قوة دافعة واضحة
- توقيت التقسيم: حجم الفريق، تعارضات النشر، متطلبات التوسع هي إشارات التقسيم
- استراتيجيات التقسيم: استخدم السياق المحدد في DDD لتوجيه التقسيم، ونمط الكُرسُن الخانق للانتقال التدريجي
- اختيار الاتصال: استخدم غير المتزامن حيثما أمكن، واجعل سلسلة الاستدعاءات المتزامنة أقصر ما يمكن
- تقسيم البيانات: الأصعب لكن الأهم، وقبول التناسق النهائي هو التحول الذهني الأساسي
قراءات إضافية
- Building Microservices - كتاب سام نيومان الكلاسيكي عن الخدمات المصغرة
- Monolith to Microservices - دليل الانتقال التدريجي
- Domain-Driven Design - كتاب إريك إيفانز الكلاسيكي عن DDD
- The Strangler Fig Pattern - نمط الكُرسُن الخانق لمارتن فاولر