إنقاذ الخادم أوتوماتيكيا من الانهيار !!!

الكاتب: SilenCker في 1 مارس 2010

بسم الله الرحمن الرحيم



من أهم مشاكل مدير خادم هو الضغط الذي يحدث فجأة على مستوى أحد خوادمه ففي كثير من المرّات يسبب هذا الضغط العالي انهيار النظام وتجمده إلى غاية القيام بـ Reboot Hardware لكي يعود هذا الخادم للعمل، وبالطبع لا يكتشف مسبب الضغط لأنه حدث لثواني ولا يؤثر على برامج المراقبة اليومية مثل الموجودة في cPanel أو جهة أخرى.

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

طبعا يمكننا فعل ذلك بكل بساطة ويسر بالاستعانة ببعض الأوامر الخاصة بنظام Linux وكذا module اختياري للـ Apache وهو mod_status يركب بشكل اوتوماتيكي على خادم الـ Apache في لوحة cPanel ونعتمد أيضا على cron job .

مهمة السكربت:

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

البداية مع السكربت:

يجب أن نجلب معدل حمل الخادم بقيمة طبيعية -تنتمي لمجموعة الأعداد الطبيعية N- وليس حقيقية أي لا تحتوي على فاصلة لكي تستطيع if الخاصة بالـ bash المقارنة بها، يمكننا جلب القيمة الأولى من ملف loadavg الموجود في مجلد proc بالاستعانة بالأمرين cat و اللغة awk وكذا الأمر cut لفصل الجزء الذي يقع قبل النقطة (.)، فيكون الأمر النهائي لجلب معدل الحمل هو:

cat /proc/loadavg | awk '{print $1}' | cut -f1 -d.

هيكلة السكربت الخاص بنا سيكون كالتالي:

1
2
3
4
5
#!/bin/bash

if [ "`cat /proc/loadavg | awk '{print $1}' | cut -f1 -d.`" -gt "15" ]; then
# هنا الأوامر التي تنفذ عندما يكون معدل الحمل أعلى من 15
fi

نبدأ بتجهيز الأوامر التي تنفذ عندما يكون معدل الحمل أعلى من 15 :

  • نبدأ بتجهيز التقرير الذي نرسله إلى صاحب الخادم:
    • نرسل له معلومات عامة عن حالة الخادم نستطيع جلب هذه المعلومات بالأمر uptime .
    • نرسل له أيضا جميع الاستعلامات الحالية على قواعد البيانات، يمكننا جلب هذه المعلومات بالأمر :
    mysql --batch -e 'SHOW PROCESSLIST'

    استعملنا الخاصية batch لتفادي الحدود التي ينشئها الأمر mysql لأنها تشوه المنظر العام عند إرسالها عبر البريد الالكتروني.

    • كما نرسل له المستخدمين الذين يقومون باستعمال cpu في الوقت الحالي وكذا عدد العمليات ونسبة استخدام cpu لكل منهم وأيضا نسبة استخدام الذاكرة لكل منهم، نستعين لإنشاء هذا بالأمر ps -eo user,pcpu,pmem وتمريره على لغة awk لتصنيف المستخدمين وجمع معدل استخدم  cpu والذاكرة لكل منهم، فيكون الأمر هو:
    ps -eo user,pcpu,pmem | tail -n +2 | awk '{num[$1]++; cpu[$1] += $2; mem[$1] += $3} END{printf("NPROC\tUSER\tCPU\tMEM\n"); for (user in cpu) printf("%d\t%s\t%.2f\t%.2f\n",num[user], user, cpu[user], mem[user]) }'
    • ونرسل له حالة الـ Apache ، المواقع وعدد زوارها في اللحظة الحالية -عدد الطلبات على كل موقع- (طبعا لن تظهر المواقع التي لا عمليات عليها)، نستعين لإنشاء هذا بـ module خاص مركب على الـ apache يسمى mod_status، يجب أولا أن نحصل على رابط الاحصائيات، بالنسبة لمالكي لوحة تحكم cPanel الرابط يكون http://localhost/whm-server-status يمكنك أن تعرف الرابط باستعمال الأمر الذي أعدده للمبتدئين :
    echo "http://localhost/$(tail -n +$((`cat -n /usr/local/apache/conf/httpd.conf | egrep "server-status" | tail -1 | awk '{print $1}'`-1)) /usr/local/apache/conf/httpd.conf | head -8 | egrep "Location" | cut -f2 -d/ | cut -f1 -d\> | head -1)"

    نستعمل الأمر أو بالأحرى المتصفح lynx لجلب صفحة الاحصائيات ونصنفها بالأمرين sort و uniq وكذا تصفية المخرج عبر egrep وfor، فيكون الأمر النهائي هو :

    for silencker in `lynx --dump http://localhost/whm-server-status | egrep '(com|net|org|info|cc)'`; do echo $silencker; done | egrep '(\.com|\.net|\.org|\.info|\.cc)' | egrep -vE '\/' | sort | uniq -c | sort -n

    طبعا مع تغيير الرابط الموجود في الأمر إلى الرابط الذي ظهر لك عند تطبيق الأمر الذي يسبقه، إذا كنت تستعمل لوحة cPanel فلا داعي لتعديه.

  • الآن انتهينا من شرح الأوامر التي تنشئ تقريرنا المفصل، نقوم بعد إنشاء التقرير بقتل العمليات الخاصة بجميع المستخدمين، إذا كنت تستعمل لوحة تحكم cPanel يمكننا استعمال الأمر :
  • for silencker in `ls /var/cpanel/users`; do killall -s 11 -u $silencker; done

    أما إذا كنت تستعمل لوحة أخرى فيمكنك أن تقوم بتضمين أسماء المستخدمين في ملف يمكنك وضعه في المسار root تحت اسم users وتغيير الأمر السابق إلى :

    for silencker in `cat /root/users`; do killall -s 11 -u $silencker; done

    وكذلك نقتل جميع العمليات الخاصة بالمستخدم nobody بالأمر :

    killall -s 11 -u nobody

السكربت النهائي :
فيكون السكربت النهائي الخاص بنا هو:

1
2
3
4
5
6
7
8
9
#!/bin/bash

fasl="\n\n\n#############################\n\n\n";

if [ "`cat /proc/loadavg | awk '{print $1}' | cut -f1 -d.`" -gt "15" ]; then
(uptime && echo -en $fasl && mysql --batch -e 'SHOW PROCESSLIST' && echo -en $fasl && ps -eo user,pcpu,pmem | tail -n +2 | awk '{num[$1]++; cpu[$1] += $2; mem[$1] += $3} END{printf("NPROC\tUSER\tCPU\tMEM\n"); for (user in cpu) printf("%d\t%s\t%.2f\t%.2f\n",num[user], user, cpu[user], mem[user]) }' && echo -en $fasl && for silencker in `lynx --dump http://localhost/whm-server-status | egrep '(com|net|org|info|cc)'`; do echo $silencker; done | egrep '(\.com|\.net|\.org|\.info|\.cc)' | egrep -vE '\/' | sort | uniq -c | sort -n) | mail -s "Server Down " silencker@gmail.com;
for silencker in `ls /var/cpanel/users`; do killall -s 11 -u $silencker; done
killall -s 11 -u nobody;
fi

مع تغيير البريد الالكتروني الموجود في السكربت إلى عنوان البريد الالكتروني الخاص بك.

قم برفع الملف إلى المجلد root تحت اسم silencker، والآن بقي لنا أن نقوم بإضافته إلى cron job وجعله يتنفذ كل دقيقة، نقوم بتطبيق الأمر crontab -e ، ونقوم بإضافة السطر التالي:

1
* * * * * sh /root/silencker

ملاحظة: إذا قمت بنسخ ولصق السكربت عبر المحرر nano أو pico فتأكد من عدم التواء الأسطر .

وفي الأخير مبروك عليك النظام :D .

الشرح مقدم من أخوكم SilenCker
يوم 1 مارس 2010 الموافق لـ15 ربيع الأول 1431

مقالات ذات علاقة

    6 ردود

  1. yasMouh قال:

    خبيييييير
    لا تعليق

    تحياتي.

  2. العتيبي قال:

    يعطيك العافيه بعد التجربه وجدت ان هناك مشكلة في السكربت ويظهر لي عند تشغيله
    : command not found 2 :
    : command not found 3 :
    : command not found 4 :
    silencker.sh: Line 8: syntax error: unexpected end if file

    نظام التشغيل centos

    • SilenCker قال:

      تأكد من النسخ الجيد وحبذا لو تستعمل أحد محررات Linux للنسخ والرفع، أو قم بتحميل السكربت بالأمر التالي على الخادم الخاص بك:

      cd /root; wget http://www.silencker.com/files/silencker.sh -O /root/silencker; chmod +x silencker; sed -i "s/silencker@gmail.com/email@email.com/g" silencker

      مع تغيير email@email.com في الأمر إلى بريدك الخاص.
      أخوك.

  3. emad قال:

    اخوي الغـالي

    ياليت شرح اكثر من كذا

    يعني مثلا السكربت النهائي انسخه كله من غير تعديل واحطه فين ؟؟

    مش فاهم بصراحة

    انتظرك

    • SilenCker قال:

      أهلا بك

      إذا لم تفهم الشرح من الأول وتريد استعمال السكربت، فابدأ بتنفيذ الشرح من النهاية (من فقرة السكربت النهائي)، قم بنسخ الكود إلى ملف silencker في المسار /root ، وقم بإعطاء الملف تصريح التنفيذ (أو التصريح 755)، وقم بإضافة سطر التنفيذ كل دقيقة في الكرون كما هو موضح، واقرأ الملاحظة الأخيرة أيضا.

      أخوك.

  4. بصراحة شرح رائع جدا
    بارك الله فيك اخي الفاضل
    وجعله الله فى ميزان حسناتك

علق على المقال

التعليق