Skip to content

التطور من التطبيق المتجانب إلى الخدمات المصغرة

مقدمة

لا توجد بنية "الأفضل"، بل فقط "الأكثر ملاءمة للمرحلة الحالية". الانتقال من التطبيق المتجانب إلى الخدمات المصغرة ليس قفزة تتم دفعة واحدة، بل عملية تطورية تدريجية مع نمو حجم العمل والفريق. التقسيم المبكر للخدمات المصغرة بنفس خطورة التقسيم المتأخر.

ماذا ستتعلم من هذه المقالة؟

بعد إتمام هذا الفصل، ستكتسب:

  • مسار التطور: فهم المراحل الأربع من التطبيق المتجانب إلى الخدمات المصغرة
  • توقيت التقسيم: معرفة متى يجب التقسيم ومتى يجب عدم التقسيم
  • استراتيجيات التقسيم: إتقان منهجية التقسيم حسب النطاق التجاري
  • أنماط الاتصال: التعرف على خيارات الاتصال المتزامن وغير المتزامن بين الخدمات
  • تقسيم البيانات: فهم تحديات وحلول تقسيم قواعد البيانات
الفصلالمحتوىالمفاهيم الأساسية
الفصل 1مسار التطور البنيويمتجانب ← وحدات ← SOA ← خدمات مصغرة
الفصل 2توقيت ومبادئ التقسيمقانون كونواي، استقلالية الفريق
الفصل 3استراتيجيات التقسيمسياق محدد في DDD، نمط الكُرسُن الخانق
الفصل 4اتصال الخدماتREST، gRPC، قوائم انتظار الرسائل
الفصل 5تقسيم البياناتتقسيم قواعد البيانات، مزامنة البيانات

1. مسار التطور البنيوي

التطور البنيوي لا تقوده التكنولوجيا، بل حجم المنظمة. عندما ينمو الفريق من 5 أشخاص إلى 500، تنخفض كفاءة التعاون في البنية المتجانبة بشكل حاد.

المرحلةالبنيةحجم الفريقالخصائص
البدايةتطبيق متجانب1~10 أشخاصجميع الشيفرة في مشروع واحد، نشر بسيط
النمومتجانب وحدات10~50 شخصًاالشيفرة مقسمة لوحدات لكن تُنشر معًا
التوسعSOA (الخدماتية)50~200 شخصتقسيم حسب خطوط العمل لخدمات ذات حبيبية خشنة
الحجم الكبيرخدمات مصغرة200+ شخصخدمات ذات حبيبية دقيقة، كل فريق يطور ويَنشر بشكل مستقل
Architecture Evolution Path
Click each stage to inspect its architecture characteristics
1
Monolithic architecture
2
Modular monolith
3
Service-oriented architecture
4
Microservices architecture
Monolithic architecture
All features are packaged in one application and share one database. It is simple and suitable for early rapid iteration.
User module
Order module
Payment module
Product module
Monolith app (one process)
MySQL
Suitable scale:Team < 10 people, DAU < 100k
Core challenge:Code is tightly coupled; a bug in one module may bring down the whole system

قانون كونواي

"المنظمات التي تصمم الأنظمة... تُنتج بنى تعادل هياكل الاتصال في تلك المنظمات." — ملفين كونواي

ببساطة: 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)

لا تُعد كتابة التطبيق المتجانب بالكامل دفعة واحدة، بل كالكُرسُن الخانق: استبدل الوحدات القديمة تدريجيًا بخدمات جديدة:

  1. أنشئ خدمة جديدة خارج التطبيق المتجانب
  2. وجّه جزءًا من الزيارات إلى الخدمة الجديدة عبر طبقة وكيل
  3. بعد التأكد من استقرار الخدمة الجديدة، انقل المزيد من الزيارات تدريجيًا
  4. استبدل الوحدة القديمة بالكامل في النهاية

4. أنماط اتصال الخدمات

الطريقةالبروتوكولالخصائصالسيناريو المناسب
RESTHTTP/JSONبسيط وعام، بيئة غنيةواجهات API الخارجية، عمليات CRUD
gRPCHTTP/2 + Protobufأداء عالٍ، أنواع قويةالاستدعاءات المتكررة بين الخدمات الداخلية
قوائم انتظار الرسائلAMQP/Kafkaفصل غير متزامن، تسوية الذروةإشعارات الأحداث، المهام غير المتزامنة
GraphQLHTTP/JSONاستعلام حسب الحاجة من جانب العميلطبقة BFF، تطبيقات الجوال

الاختيار بين المتزامن وغير المتزامن

  • تحتاج نتيجة فورية ← متزامن (REST/gRPC)
  • لا تحتاج نتيجة فورية ← غير متزامن (قائمة انتظار الرسائل)
  • حدث واحد يُفعّل عدة إجراءات ← غير متزامن (نشر-اشتراك)

القاعدة العامة: استخدم غير المتزامن حيثما أمكن، فكلما طالت سلسلة الاستدعاءات المتزامنة، أصبح النظام أكثر هشاشة.


5. تقسيم البيانات: الجزء الأصعب

الألم الأكبر في تقسيم الخدمات المصغرة ليس تقسيم الشيفرة، بل تقسيم قواعد البيانات. يجب أن تمتلك كل خدمة قاعدة بياناتها الخاصة، لكن هذا يعني أن الاستعلامات عبر الخدمات تصبح صعبة.

التحديالوصفالحل
JOIN عبر الخدماتلا يمكن عمل JOIN مباشر لجداول خدمتيناستعلام مركب عبر API، تكرار البيانات
المعاملات الموزعةالمعاملات عبر قواعد البيانات لا يمكن استخدام المعاملات المحليةSaga، جدول الرسائل المحلي
تناسق البياناتبيانات عدة خدمات قد تكون غير متسقة مؤقتًاالتناسق النهائي، الأحداث
نقل البياناتمن قاعدة مشتركة إلى قاعدة مستقلةفترة كتابة مزدوجة، أدوات مزامنة البيانات

الخلاصة

الانتقال من التطبيق المتجانب إلى الخدمات المصغرة عملية تدريجية، وليس ثورة تتم دفعة واحدة.

نراجع النقاط الرئيسية في هذا الفصل:

  1. مسار التطور: متجانب ← متجانب وحدات ← SOA ← خدمات مصغرة، لكل خطوة قوة دافعة واضحة
  2. توقيت التقسيم: حجم الفريق، تعارضات النشر، متطلبات التوسع هي إشارات التقسيم
  3. استراتيجيات التقسيم: استخدم السياق المحدد في DDD لتوجيه التقسيم، ونمط الكُرسُن الخانق للانتقال التدريجي
  4. اختيار الاتصال: استخدم غير المتزامن حيثما أمكن، واجعل سلسلة الاستدعاءات المتزامنة أقصر ما يمكن
  5. تقسيم البيانات: الأصعب لكن الأهم، وقبول التناسق النهائي هو التحول الذهني الأساسي

قراءات إضافية