دليل عملي

تنبيهات امتلاء القرص والذاكرة على VPS دون منظومة مراقبة

الأمان والمراقبة13 دقيقةً للقراءةعدد الخطوات: 9

يمتلئ قرص، فتتوقف قاعدة البيانات، ويعلم العميل قبلكم. الكلفة تدخّل عاجل وثقة مهزوزة. أما منظومة مراقبة كاملة فهي خادم ثانٍ يلزم صيانته، ولذلك تتخلى وكالات كثيرة عنها ولا تراقب شيئًا. يضع هذا الدليل ستة تنبيهات دنيا بلغة shell على كل VPS: القرص، inodes، الذاكرة، الخدمات، الشهادات، النسخ الاحتياطية. ويُراقَب الفحص نفسه بنبضة خارجية.

المحتويات· القرص الممتلئ لا يُنبّه أحدًا1/14
  1. 01القرص الممتلئ لا يُنبّه أحدًا
  2. 02التنبيهات الستة الدنيا والنبضة، على كل VPS
  3. 03المتطلبات بالأرقام: لا شيء تقريبًا
  4. 04القرص والـ inodes: العتبات وما يزيحها
  5. 05إعداد المنظومة في ساعة واحدة
  6. 06الذاكرة: OOM النواة أم حد cgroup
  7. 07OnFailure: ما يغطيه وما لا يغطيه
  8. 08الشهادات والنسخ: التنبيه على غياب النجاح
  9. 09سكربتات خاصة أم منظومة مراقبة
  10. 10راقبوا المراقِب
  11. 11استكشاف الأخطاء: الأعطال التي تتكرر
  12. 12الرسائل والأعراض مع علاجها
  13. 13التوثيق الرسمي
  14. 14تنبيهات بسيطة ومتطابقة على كل VPS

القرص الممتلئ لا يُنبّه أحدًا

يتكرر السيناريو نفسه. يعمل VPS لعميل منذ أشهر، وتكتب قاعدة البيانات سجلاتها، وتتراكم النسخ الاحتياطية، وفي صباح ما تتوقف الخدمة. لم يصدر أي تنبيه، ويعلم العميل قبلكم. في PostgreSQL، تُظهر حالة أُبلغ عنها في القائمة البريدية الرسمية للمشروع السطر الدقيق: PANIC: could not write to file "pg_wal/xlogtemp.11399": No space left on device. والـ PANIC ليس مجرد تحذير: فالخادم لم يعد قادرًا على تسجيل عمليات الكتابة، فيتوقف، ولا يعاود التشغيل سليمًا إلا بعد تحرير مساحة.

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

التنبيهات الستة الدنيا والنبضة، على كل VPS

  • القرص — عتبتان: 80 % تحذيرًا و90 % حرجًا، على كل نقطة ربط مهمة.
  • الـ inodes — قد يرفض القرص الكتابة رغم بقاء بايتات حرة إذا استُنفدت الـ inodes.
  • الذاكرة وOOM — اكتشاف أن النواة قتلت عملية، لا مجرد ارتفاع استهلاك الذاكرة.
  • خدمات systemd — التنبيه حين تدخل قاعدة البيانات أو خادم الويب أو الوكيل حالة failed.
  • الشهادات — التنبيه قبل 21 يومًا من الانتهاء، حين يفشل التجديد التلقائي بصمت.
  • النسخ الاحتياطية — التنبيه على غياب نجاح حديث، لا على خطأ صريح فقط.
  • الفحص نفسه — نبضة خارجية تنبّهكم حين تتوقف التنبيهات عن الإرسال.

المتطلبات بالأرقام: لا شيء تقريبًا

كل ما يلي يتسع في بضع عشرات من أسطر shell وفق POSIX. تحتاجون إلى VPS بنظام Linux مزوّد بـ curl وcron أو مؤقّتات systemd، وصلاحية root للكتابة في /usr/local/bin و/etc، ونحو 1 ميغابايت من القرص. وتكلفة الذاكرة هي تكلفة سكربت يدوم ثانية كل خمس دقائق: لا تُذكر، حتى على أصغر VPS.

ويكمل المنظومةَ عنصران خارجيان: قناة استقبال (بوت Telegram أو أي webhook يمكن بلوغه عبر HTTP) وخدمة نبضة تستقبل ping منتظمًا وتنبّهكم حين يتوقف. وبخصوص هذه الأخيرة، تقدّم Healthchecks.io خطة مجانية محدودة بـ 20 مهمة و100 سجل لكل مهمة، وهو يكفي أسطولًا صغيرًا؛ تحققوا من هذه الحدود في المصدر قبل الاعتماد عليها. وإن لم ترغبوا في أي خدمة طرف ثالث، فإن وضع push في Uptime Kuma يؤدي الدور نفسه على جهاز تملكونه.

القرص والـ inodes: العتبات وما يزيحها

الأمر المفيد هو df -h --output=pcent,target: لا يعرض سوى النسبة ونقطة الربط، وهذا سهل القراءة والمعالجة. وبالنسبة للـ inodes تصبح الفكرة نفسها df --output=ipcent,target. قد يستهلك مجلد جلسات أو ملفات تخزين مؤقت صغيرة كل الـ inodes في نظام ملفات ext4 بينما يعرض df -h امتلاءً بنسبة 40 % فقط: وتفشل الكتابة مع ذلك بالرسالة نفسها No space left on device.

وثمة دقة ثانية. في ext4 يُحجز 5 % من الكتل افتراضيًا للعمليات المميّزة، بحسب صفحة دليل tune2fs؛ وبذلك تواصل خدمات النظام الكتابة حين يملأ مستخدم عادي القرص. والنتيجة: الخدمة التي تعمل بحساب غير مميّز، مثل قاعدة البيانات، يرى df يعرض 100 % بينما القرص مستخدم بنحو 95 %. ومن هنا العتبتان المختارتان: 80 % لإتاحة وقت للتصرف، و90 % للتصرف فورًا. انتظار 100 % يعني التنبيه بعد الانقطاع.

إعداد المنظومة في ساعة واحدة

  1. إنشاء قناة التنبيه

    أنشئوا بوت Telegram عبر BotFather، ودوّنوا الرمز المميز ومعرّف المحادثة التي ستستقبل الرسائل. تتبع كل طلبات واجهة Bot الصيغة https://api.telegram.org/bot<token>/METHOD_NAME، وطريقة الإرسال هي sendMessage. وإن فضّلتم webhook (Slack أو Mattermost أو ntfy) فلا يتغير سوى السطر الأخير من سكربت الإرسال.

  2. كتابة ملف البيئة

    sudo mkdir -p /var/lib/alerte-vps
    sudo install -m 600 /dev/null /etc/alerte-vps.env
    ثم أضيفوا إليه أربعة أسطر: TG_TOKEN=... وTG_CHAT=... وHC_URL=https://hc-ping.com/<uuid> (فحص كل خمس دقائق) وHC_URL_JOUR=https://hc-ping.com/<other-uuid> (فحص يومي). الوضع 600 يُبقي الرمز مقروءًا لـ root وحده.

  3. كتابة سكربت الإرسال مع منع التكرار

    احفظوا هذه الأسطر في /usr/local/bin/alerte-envoi ثم اجعلوا الملف قابلًا للتنفيذ بالأمر sudo chmod 755. يمنع ملف القفل لكل رسالة أن تُزعجوا كل خمس دقائق بالتنبيه نفسه: فالرسالة المطابقة لا تُعاد إلا بعد ساعة.
    #!/bin/sh
    . /etc/alerte-vps.env
    f=/var/lib/alerte-vps/$(echo "$1" | md5sum | cut -c1-12)
    [ -n "$(find "$f" -mmin -60 2>/dev/null)" ] && exit 0
    touch "$f"
    curl -fsS -m 10 --retry 3 "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" -d chat_id="${TG_CHAT}" --data-urlencode text="$(hostname) $1"

  4. فحص القرص والـ inodes

    في /usr/local/bin/alerte-rapide (مع shebang #!/bin/sh) أضيفوا الحلقتين التاليتين. يستبعد المرشّح grep -v أنظمة الملفات التي لا تعرض inodes وتطبع شرطة.
    df --output=pcent,target -x tmpfs -x devtmpfs | tail -n +2 | while read p m; do n=${p%\%}; if [ "$n" -ge 90 ]; then alerte-envoi "CRIT disk $m"; elif [ "$n" -ge 80 ]; then alerte-envoi "WARN disk $m"; fi; done
    df --output=ipcent,target -x tmpfs -x devtmpfs | tail -n +2 | grep -v '^ *-' | while read p m; do [ "${p%\%}" -ge 90 ] && alerte-envoi "INODES $m"; done

  5. اكتشاف العمليات التي قتلها OOM killer

    لا يفعل العدّاد oom_kill في /proc/vmstat سوى الازدياد منذ الإقلاع. تُقارن قيمته بالقيمة السابقة المحفوظة في ملف؛ وبعد إعادة التشغيل يبدأ العدّاد من الصفر فتخطئ المقارنة مرة واحدة ثم تستقيم.
    n=$(awk '/^oom_kill/ {print $2}' /proc/vmstat)
    old=$(cat /var/lib/alerte-vps/oom 2>/dev/null || echo 0)
    [ "$n" -gt "$old" ] && alerte-envoi "OOM kill"
    echo "$n" > /var/lib/alerte-vps/oom

  6. إضافة النبضة والجدولة

    أنهوا alerte-rapide بالـ ping. لا يُبلغ هذا السطر إلا إذا بلغ السكربت نهايته؛ فإن توقف cron أو صار القرص للقراءة فقط أو تعطل السكربت، توقف الـ ping وتنبّهكم الخدمة الخارجية. ثم أضيفوا سطري cron في /etc/cron.d/alerte-vps.
    . /etc/alerte-vps.env; curl -fsS -m 10 --retry 5 -o /dev/null "$HC_URL"
    PATH=/usr/local/bin:/usr/bin:/bin
    */5 * * * * root /usr/local/bin/alerte-rapide
    30 7 * * * root /usr/local/bin/alerte-quotidien

  7. فحص الشهادات والنسخ الاحتياطية مرة يوميًا

    في /usr/local/bin/alerte-quotidien أضيفوا هذه الأسطر. يفشل الخيار -checkend في openssl x509 إذا انتهت صلاحية الشهادة خلال عدد الثواني المحدد؛ و1814400 ثانية تساوي 21 يومًا. ويُنبّه اختبار النسخ حين لا يوجد ملف .gz غير فارغ أحدث من 1560 دقيقة، أي 26 ساعة. وينتهي السكربت بـ ping خاص به نحو الفحص الثاني: فبدونه قد يتوقف الفحص اليومي بصمت دون أن يلحظه أحد.
    echo | openssl s_client -servername your-domain.com -connect your-domain.com:443 2>/dev/null | openssl x509 -noout -checkend 1814400 || alerte-envoi "CERT your-domain.com"
    find /var/backups/app -name '*.gz' -mmin -1560 -size +1k | grep -q . || alerte-envoi "BACKUP absent"
    . /etc/alerte-vps.env; curl -fsS -m 10 --retry 5 -o /dev/null "$HC_URL_JOUR"

  8. ربط الخدمات الحرجة بـ OnFailure

    أنشئوا /etc/systemd/system/[email protected] بالمحتوى التالي ثم نفّذوا sudo systemctl daemon-reload.
    [Unit]
    Description=Alerte echec de %i
    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/alerte-envoi "FAILED %i"
    ولكل خدمة تريدون مراقبتها، افتحوا drop-in بالأمر sudo systemctl edit mariadb.service وأضيفوا هذين السطرين.
    [Unit]
    OnFailure=notify-failure@%n.service

  9. افتعال تنبيه للاختبار ثم التنظيف

    تنبيه لم يُطلَق قط ليس تنبيهًا. تحققوا أولًا من المساحة الحرة، وأنشئوا ملفًا كبيرًا بما يكفي لتجاوز العتبة، وشغّلوا السكربت يدويًا، ثم احذفوا الملف. وإن لم تصل الرسالة فالخلل في القناة، ومن الأفضل اكتشافه الآن.
    df -h --output=pcent,target /var/tmp
    sudo fallocate -l 2G /var/tmp/test-alerte.img
    sudo /usr/local/bin/alerte-rapide
    sudo rm /var/tmp/test-alerte.img

الذاكرة: OOM النواة أم حد cgroup

هناك آليتان تقتلان عملية لنقص الذاكرة، ولا تُقرآن في المكان نفسه. الأولى هي OOM killer في النواة حين تنقص الذاكرة الجهاز كله: فيحتوي سجل النواة على رسالة من نوع Out of memory: Killed process يتيح journalctl -k العثور عليها. والثانية هي حد cgroup. وبحسب توثيق systemd، حين يتعذر احتواء استهلاك وحدة تحت MemoryMax= يُستدعى OOM killer داخل الوحدة: وقد يبقى لبقية الجهاز ذاكرة حرة.

ويغطي العدّاد oom_kill في /proc/vmstat الحالة الأولى على مستوى الجهاز. أما لوحدة بعينها فيعرض الملف memory.events في cgroup الخاص بها عدّادًا oom_kill خاصًا، تعرّفه وثائق النواة بأنه عدد عمليات الـ cgroup التي قتلها أي نوع من OOM killer. وعلى VPS يستضيف تطبيقًا شرهًا، مثل التطبيق الموصوف في دليل n8n وOOM في الإنتاج، يفسّر هذا العدّاد الثاني التوقفات التي لا يُظهرها free -h أبدًا.

OnFailure: ما يغطيه وما لا يغطيه

بحسب توثيق systemd، يسرد OnFailure= الوحدات التي تُفعَّل حين تدخل الوحدة حالة failed. يتلقى القالب [email protected] اسم الوحدة المعطوبة عبر المحدّد %n، ويمكن لرسالة التنبيه أن ترفق مخرجات systemctl status أو journalctl -u للسياق.

والحد بنيوي: الخدمة التي تعمل لكنها لم تعد تستجيب لم تمرّ قط بحالة failed، فلا يقول OnFailure= شيئًا. والخدمة التي يعيد Restart= تشغيلها لا تبلغ تلك الحالة إلا عند بلوغ حد المحاولات. ولهذه الحالات أضيفوا مسبارًا بسيطًا للتطبيق، مثل curl على عنوان صحة التطبيق، في السكربت السريع. وقد عولجت صيغة المؤقّتات وcron في دليل cron ومؤقّتات systemd، فلا داعي لتكرارها هنا.

الشهادات والنسخ: التنبيه على غياب النجاح

قد يفشل التجديد التلقائي للشهادة بصمت أسابيع: سجل DNS عُدّل، أو منفذ محجوب، أو إضافة معطوبة. ولا تنتهي الشهادة في ذلك اليوم بل بعد تسعين يومًا، ولا يتذكر أحد. ويستجوب اختبار openssl ما يتلقاه الزائر فعلًا، وهذا أفضل من قراءة ملف على القرص. وعلى خادم تديره Certbot، يسرد certbot certificates الشهادات وتواريخ انتهائها، ويتحقق certbot renew --dry-run من أن التجديد القادم سينجح.

المنطق نفسه للنسخ الاحتياطية. التنبيه المرتبط بفشل سكربت النسخ لا يرى الحالة التي لم يُشغَّل فيها السكربت قط. والتنبيه الصحيح يُوضع على الغياب: لا ملف حديث، أو ملف حجمه صفر. وهذا ما يفعله السطر find -mmin في السكربت اليومي، ولذلك يصمت حين يسير كل شيء على ما يرام ويتكلم فور توقف سلسلة النسخ، أيًّا كان السبب.

سكربتات خاصة أم منظومة مراقبة

مرّر الجدول أفقيًا

المعيارسكربتات shell وOnFailureBeszel أو Uptime Kuma
الإعدادساعة واحدة، بضعة ملفات في `/usr/local/bin`hub يلزم استضافته ووكلاء يُثبَّتون على كل VPS
الأسطول المستهدفمن 1 إلى 5 خوادم VPS، وحتى 10 إذا تطابقت العتباتما بعد 5 إلى 10 خوادم VPS، أو حين تلزم المقارنة
السجل والرسوملا شيء، فقط لحظة التنبيهرسوم واتجاهات ومقارنة بين الأجهزة
الصيانةلا شيء يُحدَّث خارج shellخادم ثانٍ وتحديثاته يلزم متابعتها
خدمات التطبيقمسبار `curl` تكتبونه بأنفسكممسابير HTTP وTCP وصفحة حالة جاهزة
عطل المراقِبتكشفه النبضة الخارجيةيلزم مراقبته على حدة، فالـ hub جهاز بدوره
متى تختارونهتنبيهات دنيا، أسطول صغير، دون خادم إضافيسجل مطلوب، أسطول متنامٍ، فريق مشترك

راقبوا المراقِب

فخ هذه السكربتات أن تتحول إلى طمأنة زائفة: تصمت لأن كل شيء سليم أو لأنها معطوبة، ويبدو الصمت واحدًا في الحالتين. وتحل نبضة الـ ping المشكلة. اضبطوا المدة المتوقعة للفحص فوق فاصل cron بقليل وأضيفوا هامش سماح: تنبيه صمت يصل متأخرًا عشرين دقيقة خير من إنذار كاذب عند كل إعادة تشغيل. واحتفظوا أيضًا بالملف /etc/alerte-vps.env في الوضع 600 ولا تضعوا الرمز في نظام التحكم بالإصدارات أبدًا.

استكشاف الأخطاء: الأعطال التي تتكرر

تتعطل التنبيهات نفسها بطرق يمكن توقعها. هذه أكثر الحالات مصادفة، مع الرسالة أو العَرَض الذي ينبغي التعرف عليه والعلاج. ويُتحقق من كل منها يدويًا قبل البحث أبعد.

الرسائل والأعراض مع علاجها

  • PANIC: could not write to file "pg_wal/...": No space left on device — المجلد الذي يحمل سجلات PostgreSQL ممتلئ. حرّروا مساحة خارج PostgreSQL أولًا (سجلات مدوَّرة، نسخ قديمة)، ولا تحذفوا ملفات pg_wal يدويًا أبدًا، ثم أعيدوا تشغيل الخدمة.
  • No space left on device بينما يعرض df -h مساحة حرة — الـ inodes مستنفدة. نفّذوا df --output=ipcent,target، وحدّدوا المجلد الذي يضم ملايين الملفات الصغيرة (جلسات، تخزين مؤقت) ونظّفوه.
  • القرص ممتلئ لكن du لا يجد المساحة — ملفات محذوفة ما زالت مفتوحة لدى عملية. يسردها sudo lsof +L1؛ وإعادة تشغيل العملية تحرر المساحة.
  • oom_kill يرتفع ولا شيء في journalctl -k — دار سجل النواة أو أن القتل ناتج عن حد MemoryMax=. اقرؤوا memory.events في مجلد cgroup الوحدة وjournalctl -u للوحدة.
  • وحدة تعمل لكنها لا تستجيب ولا تنبيه — هذا حد OnFailure=. أضيفوا مسبار curl على عنوان الصحة ونبّهوا بحسب رمز الإرجاع.
  • لا رسالة Telegram ولا خطأ ظاهر — يرسل cron مخرجات السكربت بريدًا محليًا لا يقرؤه أحد. شغّلوا alerte-envoi test يدويًا بـ sudo واقرؤوا ردّ curl.
  • الشهادة تقترب من الانتهاء رغم تثبيت Certbot — نفّذوا certbot renew --dry-run واقرؤوا خطأ التحقق، ثم صحّحوا DNS أو المنفذ المعني.

التوثيق الرسمي

كل سلوك موصوف هنا مصدره مرجع أولي. بالنسبة إلى OnFailure= راجعوا صفحة دليل systemd.unit؛ وبالنسبة إلى MemoryMax= راجعوا systemd.resource-control؛ وللعدّادين oom وoom_kill راجعوا توثيق cgroups v2 في النواة؛ وللـ 5 % المحجوزة راجعوا صفحة دليل tune2fs. وفي جانب الإرسال تصف واجهة Telegram Bot شكل الطلبات، وتصف وثائق واجهة Healthchecks عناوين الـ ping، مع صفحة الأسعار لحدود الخطة المجانية. وبخصوص التجديد راجعوا توثيق Certbot. ورسالة PostgreSQL المقتبسة مصدرها نقاش في القائمة البريدية الرسمية للمشروع.

تنبيهات بسيطة ومتطابقة على كل VPS

ستة تنبيهات ونبضة لا تحل محل منظومة مراقبة، لكنها تغطي ما يُسقط خادمًا فعلًا: القرص والـ inodes والذاكرة والخدمات والشهادات والنسخ. والمكسب الرئيسي هو التجانس: العتبات نفسها والرسائل نفسها وطريقة الاختبار نفسها على كل جهاز في الأسطول. وحين يكبر الأسطول أو يلزم سجل تاريخي، يُمهَّد الانتقال إلى منظومة في دليل Beszel وفي دليل التنبيهات الاستباقية مع Beszel وUptime Kuma، وهما يعالجان التثبيت من أوله إلى آخره.

أسطول VPS لعملاء، وعتبات متجانسة

على ServOrbit.com تجتمع نطاقات أسطول العملاء واستضافاته وخوادمه في مكان واحد وفضاء إدارة واحد. ويتوفر خيار إدارة VPS للعملاء الذين لا يريدون إدارة خادمهم بأنفسهم.

بحاجة إلى مساعدة؟

تصفّح مركز المساعدة والأسئلة الشائعة، أو تواصل مع فريقنا — معاودة اتصال أو WhatsApp أو بريد إلكتروني. الدعم بـالعربية والفرنسية والإنجليزية.

راسلنا على WhatsAppيُفتح في علامة تبويب جديدة