خوادمنا تنهار والأخرى في سبات: كيف أنقذنا “موازن الأحمال” من جحيم التوزيع غير العادل؟

يا جماعة الخير، السلام عليكم ورحمة الله وبركاته. معكم أخوكم أبو عمر.

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

فجأة، الابتسامة اختفت. الخادم الأول (Server 1) مؤشر الـ CPU عنده نط للـ 100% وصار لونه أحمر قاني. الإنذارات بلشت توصل على تلفوني زي المطر. بغمضة عين، الخادم الأول انهار. قلت بسيطة، “مش قصة”، موازن الأحمال (Load Balancer) المفروض ذكي كفاية يوزع الضغط على الأربع خوادم الباقية. بس اللي صار كان العكس تمامًا!

الخادم الثاني بلش يعاني، وبعده الثالث… والمصيبة إنه لما أطلّع على الخادم الرابع والخامس، بلاقيهم مرتاحين! المعالج تبعهم يا دوب واصل 20%، كأنهم “قاعدين بشربوا شاي وبحضروا الدراما”. موازن الأحمال، اللي جبناه ليكون المنقذ، صار هو الجلّاد اللي بوجه المستخدمين لحتفهم على خوادم محملة فوق طاقتها أو ميتة أصلًا. كانت ليلة من ليالي الجحيم التقني، ولكنها علمتنا درسًا لن ننساه أبدًا.

في هالمقالة، بدي أحكيلكم القصة كاملة، ونغوص مع بعض في تفاصيل موازنات الأحمال، ونعرف ليش ممكن تفشل بهالشكل الدرامي، وكيف ممكن ننقذ الموقف ونعمل “شغل نظيف” يضمن أداء عالي واستقرار دائم.

ما هو موازن الأحمال (Load Balancer)؟ وليش هو مهم؟

قبل ما نحكي عن المشكلة، خلينا نرجع خطوة للوراء ونسأل: شو هو موازن الأحمال؟

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

تقنيًا، موازن الأحمال هو جهاز أو برنامج بيستقبل كل الطلبات (Traffic) اللي جاية على تطبيقك، وبقوم بتوزيعها على مجموعة من الخوادم (Servers) اللي بتشغل نفس التطبيق. الهدف الأساسي هو:

  • توزيع الحمل: منع أي خادم منفرد من التحميل الزائد والانهيار.
  • زيادة التوافرية (High Availability): إذا انهار أحد الخوادم، يقوم موازن الأحمال تلقائيًا بتحويل الطلبات إلى الخوادم السليمة، وبالتالي يبقى تطبيقك يعمل دون انقطاع.
  • التوسع الأفقي (Horizontal Scaling): يسمح لك بإضافة المزيد من الخوادم بسهولة مع نمو عدد المستخدمين، دون الحاجة لترقية الخادم نفسه (التوسع العمودي).

جحيم التوزيع غير العادل: الأسباب الخفية

طيب، إذا كان موازن الأحمال بهالروعة، ليش خوادمنا كانت بتنهار؟ ليش التوزيع كان ظالمًا؟ الجواب يكمن في “كيف” يقرر موازن الأحمال توزيع الطلبات. هذه “الكيف” تسمى خوارزمية التوزيع (Load Balancing Algorithm). وهنا تكمن الكثير من الفخاخ.

خوارزمية التوزيع الدوري (Round Robin): البساطة التي تخدع

هذه هي الخوارزمية الأبسط والأكثر شيوعًا. الفكرة بسيطة جدًا: أول طلب يروح للخادم 1، الثاني للخادم 2، الثالث للخادم 3، وهكذا بشكل دائري. لما يوصل لآخر خادم، برجع يبدأ من الأول.

المشكلة: هذه الخوارزمية غبية! هي تفترض أن كل الخوادم متساوية في القوة، وأن كل الطلبات تتطلب نفس الوقت للمعالجة. وهذا افتراض خاطئ في العالم الحقيقي. قد يكون هناك طلب واحد (مثلاً، إنشاء تقرير معقد) يأخذ 30 ثانية على الخادم 1، بينما 100 طلب آخر (مثل عرض صفحة بسيطة) يأخذ كل منها 0.1 ثانية على الخوادم الأخرى. خوارزمية Round Robin لا ترى هذا الفرق، وستستمر في إرسال الطلبات بالتساوي، مما يؤدي إلى تكدس الطلبات على الخادم المشغول وانهياره.

فخ الجلسات الثابتة (Sticky Sessions)

وهذا يا جماعة كان السبب الرئيسي في كارثتنا هذيك الليلة. “الجلسات الثابتة” أو كما تعرف بـ (Session Persistence/Affinity) هي ميزة في موازن الأحمال تجعله يرسل كل طلبات المستخدم الواحد إلى نفس الخادم دائمًا.

لماذا نستخدمها؟ في بعض التطبيقات القديمة أو التي صممت بطريقة معينة، يتم تخزين معلومات جلسة المستخدم (مثل محتويات عربة التسوق) في ذاكرة الخادم نفسه. فإذا تم توجيه طلب المستخدم التالي لخادم آخر، فإن هذا الخادم الجديد لن يعرف شيئًا عن عربة التسوق، وستظهر فارغة! “شغلة بتجلط” المستخدم طبعًا. الجلسات الثابتة تحل هذه المشكلة “ظاهريًا” عن طريق “لصق” المستخدم بنفس الخادم.

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

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

مهمة الإنقاذ: خطوات عملية للخروج من المأزق

في خضم الفوضى، كان علينا التحرك بسرعة وبذكاء. إليكم الخطوات التي اتبعناها لتشخيص المشكلة وحلها:

الخطوة الأولى: التشخيص والمراقبة

أول شيء فعلناه هو النظر إلى لوحات المراقبة (Dashboards) الخاصة بنا (كنا نستخدم Prometheus و Grafana). رأينا بوضوح أن استهلاك الـ CPU والذاكرة كان مرتفعًا جدًا على خوادم معينة ومنخفضًا على أخرى. هذا أكد لنا أن المشكلة في التوزيع وليست في الكود نفسه. ثم نظرنا إلى إعدادات موازن الأحمال (كنا نستخدم Nginx وقتها) ورأينا الكارثة: كنا نستخدم خوارزمية `ip_hash` لتطبيق الجلسات الثابتة.

الخطوة الثانية: تغيير خوارزمية التوزيع

كان الحل الفوري هو التخلص من الجلسات الثابتة والتحول إلى خوارزمية أذكى. الخيار الأفضل في معظم الحالات هو “أقل الاتصالات” (Least Connections).

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

هكذا يبدو التغيير في ملف إعدادات Nginx:


# الإعداد القديم الكارثي (Sticky Session)
upstream backend_servers {
    ip_hash; # هذا يربط المستخدم بنفس الخادم بناءً على الـ IP
    server server1.example.com;
    server server2.example.com;
    server server3.example.com;
}

# الإعداد الجديد المنقذ (Least Connections)
upstream backend_servers {
    least_conn; # هذا يرسل الطلب للخادم الأقل انشغالاً
    server server1.example.com;
    server server2.example.com;
    server server3.example.com;
}

server {
    listen 80;
    server_name myapp.com;

    location / {
        proxy_pass http://backend_servers;
    }
}

الخطوة الثالثة: تفعيل فحوصات الصحة (Health Checks)

مشكلة أخرى كانت أن موازن الأحمال كان لا يزال يحاول إرسال بعض الطلبات إلى الخادم المنهار. السبب هو أن “فحص الصحة” لم يكن مفعلاً بالشكل الصحيح.

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

في Nginx (النسخة التجارية) أو باستخدام أدوات مثل HAProxy، يمكنك ضبط هذا بشكل مفصل. مثال في HAProxy:


backend web_servers
    balance roundrobin # أو leastconn
    option httpchk GET /health-check # مسار فحص الصحة
    http-check expect status 200 # توقع أن تكون الاستجابة 200 OK
    server web1 192.168.1.11:80 check inter 5s rise 2 fall 3
    server web2 192.168.1.12:80 check inter 5s rise 2 fall 3

هذا الإعداد يخبر HAProxy أن يفحص الخوادم كل 5 ثوانٍ. إذا فشل الخادم 3 مرات متتالية، يتم إخراجه من الخدمة. وإذا نجح مرتين متتاليتين، يعود للخدمة.

نصائح أبو عمر الذهبية لموازنة الأحمال ⚖️

بعد هذيك الليلة، صارت عندي مجموعة قواعد ذهبية بتعامل فيها مع أي بنية تحتية تحتاج لتوسع وأداء عالي:

  1. راقب ثم راقب ثم راقب: لا تضع موازن الأحمال وتنساه. استخدم أدوات مراقبة لترى توزيع الحمل على خوادمك بشكل مباشر. الأرقام لا تكذب.
  2. اختر الخوارزمية الصحيحة: لا تستخدم Round Robin إلا في أبسط الحالات. ابدأ بـ `least_conn` فهي نقطة انطلاق ممتازة لمعظم التطبيقات. إذا كانت خوادمك مختلفة في القوة، استخدم `Weighted Round Robin` لتعطي وزنًا أكبر للخوادم الأقوى.
  3. اهرب من الجلسات الثابتة: ابذل كل جهدك لتجعل تطبيقك `Stateless`. هذا سيعطيك حرية ومرونة لا تصدق في التوسع. استخدم Redis أو خدمة ذاكرة تخزين مؤقت موزعة لتشارك الجلسات بين الخوادم.
  4. فحوصات الصحة ليست رفاهية: هي خط الدفاع الأول ضد انقطاع الخدمة. تأكد من أنها مفعلة وتعمل بشكل صحيح. اجعل نقطة النهاية (endpoint) الخاصة بالفحص بسيطة وسريعة جدًا (لا تقم بعمليات معقدة فيها).
  5. لا تنسَ الشبكة: أحيانًا لا تكون المشكلة في الخوادم أو موازن الأحمال، بل في الشبكة بينهما. تأكد من أن سرعة الشبكة بين موازن الأحمال وخوادمك عالية وزمن الوصول (latency) منخفض.

الخلاصة يا غوالي

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

أتمنى أن تكون هذه القصة والتفاصيل التقنية مفيدة لكم. تذكروا دائمًا، أفضل الأنظمة هي تلك التي تُبنى على فهم عميق للمبادئ الأساسية، وليس فقط على تطبيق أعمى للحلول الجاهزة. بالتوفيق في مشاريعكم! 🚀

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

الشبكات والـ APIs

كانت خوادمنا تستجدي التحديثات: كيف أنقذتنا ‘خطاطيف الويب’ (Webhooks) من جحيم الاستقصاء المستمر (Polling)؟

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

17 مايو، 2026 قراءة المزيد
الحوسبة السحابية

كانت بنيتنا التحتية قصراً من رمال: كيف أنقذتنا “البنية التحتية ككود” (IaC) من جحيم البيئات المتضاربة؟

أشارككم قصة حقيقية عن ليلة كادت أن تنهار فيها شركتنا بسبب الفوضى في البنية التحتية، وكيف كانت "البنية التحتية ككود" (IaC) طوق النجاة الذي انتشلنا...

17 مايو، 2026 قراءة المزيد
التوظيف وبناء الهوية التقنية

كان ملفي الشخصي مقبرة لمشاريع الدورات: كيف أنقذتني ‘المساهمة في المصادر المفتوحة’ من جحيم الرفض التلقائي؟

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

17 مايو، 2026 قراءة المزيد
التوسع والأداء العالي والأحمال

كانت قاعدة بياناتنا تتوسل الرحمة: كيف أنقذنا التخزين المؤقت (Caching) من جحيم الاستعلامات البطيئة

قصة حقيقية من واقع العمل عن كيفية انهيار نظامنا تحت ضغط الاستعلامات المتكررة، وكيف كان التخزين المؤقت (Caching) هو طوق النجاة. مقالة عملية للمطورين تشرح...

17 مايو، 2026 قراءة المزيد
التكنلوجيا المالية Fintech

كان التحقق من هوية عملائنا يستغرق أياماً: كيف أنقذنا الذكاء الاصطناعي (eKYC) من جحيم الإجراءات اليدوية؟

بصفتي مبرمجاً فلسطينياً، سأروي لكم حكايتنا مع كابوس التحقق اليدوي من هوية العملاء (KYC) وكيف كانت رحلة الانتقال إلى التحقق الإلكتروني (eKYC) باستخدام الذكاء الاصطناعي...

17 مايو، 2026 قراءة المزيد
البنية التحتية وإدارة السيرفرات

كانت أعطالنا تكتشف بعد فوات الأوان: كيف أنقذنا Prometheus من جحيم المراقبة التفاعلية؟

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

17 مايو، 2026 قراءة المزيد
ادارة الفرق والتنمية البشرية

كانت فرقنا صامتة أمام الأخطاء: كيف أنقذتنا ‘السلامة النفسية’ من جحيم ثقافة اللوم؟

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

17 مايو، 2026 قراءة المزيد
البودكاست