Software Architecture

التوسع الأفقي مقابل التوسع الرأسي: اختيار النمط المناسب لخدمات مايكرو ذات الحركة المرورية العالية

عندما تتطور التطبيقات من نماذج أولية (MVPs) إلى بيئات إنتاجية ذات حركة مرور عالية، تواجه بنية "الخادم الواحد" حتماً حدوداً. أمام المهندسين والمطورين الكبار، يعد القرار بين التوسع الأفقي (إضافة المزيد من العقد) والتوسع الرأسي (ترقية العقد الحالية) أكثر من مجرد خيار في التكوين؛ بل هو محدد معماري جوهري. بينما يوفر التوسع الرأسي حلاً سريعاً للارتفاعات المفاجئة في الحمل، يوفر التوسع الأفقي المرونة المطلوبة للأنظمة الموزعة الحديثة. يستكشف هذا المنشور المقايضات التقنية لمساعدتك في اختيار المسار الصحيح.

التوسع الرأسي: مسار أقل مقاومة

يشير التوسع الرأسي، والذي يُشار إليه غالباً بـ "التوسع لأعلى"، إلى زيادة القوة الحاسوبية لجهاز واحد من خلال إضافة المزيد من نوى المعالج (CPU)، أو الذاكرة العشوائية (RAM)، أو مساحة التخزين. هذا النهج بديهي وغالباً ما يتطلب تغييرات طفيفة في الكود. بالنسبة للتطبيقات ذات الحالة (Stateful) أو الأنظمة أحادية الكتلة القديمة (Legacy Monoliths) التي لم تُصمم للتوزيع، يمكن أن يكون التوسع الرأسي هو الحل العملي الأقصر أجلاً على المدى القصير.

ومع ذلك، فإن للتوسع الرأسي حدوداً صارمة. أنت مقيد بالمواصفات القصوى لجهاز فيزيائي أو افتراضي واحد. علاوة على ذلك، فإنه يقدم نقطة فشل وحيدة (SPOF). إذا تعطل ذلك الخادم الضخم الواحد، فإن الخدمة بأكملها تنقطع. بالإضافة إلى ذلك، تعاني الخوادم عالية التكلفة من عوائد متناقصة بسبب قيود الأجهزة ومنحنيات التكلفة الأسية.

التوسع الأفقي: المعيار الأصلي للسحابة

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

المزايا الرئيسية

  • المرونة: إذا تعطلت عقدة واحدة، تستمر العقد الأخرى في التعامل مع حركة المرور، مما يضمن توفرًا عاليًا.
  • قابلية التوسع اللانهائية: نظرياً، يمكنك إضافة عدد لا نهائي من العقد طالما أن موزع الحمل والبنية التحتية يدعمان ذلك.
  • كفاءة التكلفة: استخدام الأجهزة القياسية غالباً ما يكون أرخص من شراء حواسيب فائقة.

مقايضة التعقيد

العيبة الرئيسية للتوسع الأفقي هي زيادة التعقيد. يجب عليك إدارة اكتشاف الخدمات، وتوازن الحمل، والأهم من ذلك، إدارة الحالة. يجب تصميم خدمات المايكرو لتكون عديمة الحالة (Stateless)، مما يعني أنها لا ينبغي أن تخزن بيانات الجلسة محلياً. بدلاً من ذلك، يجب تحميل الحالة إلى قواعد بيانات خارجية أو طبقات تخزين مؤقت مثل Redis.

تنفيذ التوسع الأفقي باستخدام Kubernetes

في بيئة Kubernetes الحديثة، غالباً ما يتم أتمتة التوسع الأفقي عبر مقياس الحاوية الأفقية (HPA). فيما يلي مثال على تكوين YAML يقوم بتوسيع نطاق نشر تلقائياً بناءً على استخدام وحدة المعالجة المركزية.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-microservice-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-microservice
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

يضمن هذا التكوين أنه عندما يتجاوز استخدام وحدة المعالجة المركزية 70٪، تقوم Kubernetes تلقائياً بتوفير حاويات (Pods) جديدة حتى حد أقصى يبلغ 10. عندما تهدأ حركة المرور، تقوم بتقليل العدد لتوفير الموارد.

الخلاصة: اتخاذ القرار الصحيح

لا توجد إجابة تناسب الجميع. إذا كنت تشغل أداة داخلية بسيطة وذات حالة (Stateful) مع حركة مرور منخفضة ومتوقعة، فقد يكون التوسع الرأسي كافياً ويوفر لك عناء إدارة الأنظمة الموزعة. ومع ذلك، بالنسبة لخدمات المايكرو الموجهة للجمهور وذات الحركة المرورية العالية، فإن التوسع الأفقي أمر لا غنى عنه لتحقيق الموثوقية والمرونة.

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

Share: