على أي سيرفر Linux حديث، تُدار "الخدمات" (مثل خادم الويب وقاعدة البيانات) عبر مدير النظام systemd بأمر systemctl للتشغيل والإيقاف والإعادة والتمكين عند الإقلاع، وتُقرأ سجلّاتها بأمر journalctl. أما "العمليات" الجارية فتُراقَب بأدوات مثل ps وtop وhtop وfree، وتُوجَّه بإشارات عبر kill وpkill، وتُضبط أولويّتها بـnice وrenice. إتقان هذه الأدوات الست هو الفرق بين من يملك VPS ومن يديره فعلًا.
بعد أن تنتهي من إعداد أول سيرفر VPS من الصفر وتؤمّن دخولك عبر أساسيات SSH للمبتدئين، تبدأ المرحلة الحقيقية: تشغيل البرمجيات وإبقاؤها حيّة. السيرفر لا يفيدك وهو صندوق صامت؛ قيمته في الخدمات التي يقدّمها — موقع يعمل، قاعدة بيانات تستجيب، مهمة تُنفَّذ في موعدها. هذا الدليل يأخذك من المفاهيم الأساسية حتى كتابة وحدة systemd مخصّصة وجدولة المهام، خطوةً خطوة وبأوامر حقيقية قابلة للنسخ.
الفرق بين الخدمة والعملية
قبل أي أمر، علينا فضّ التباس شائع. العملية (Process) هي أي برنامج قيد التنفيذ في لحظة معيّنة؛ لها رقم تعريفي فريد يُسمّى PID، ومالك (مستخدم)، وذاكرة، ونصيب من المعالج. حين تكتب أمرًا في الطرفية، يُنشئ النظام عملية لتنفيذه، وقد تنتهي بعد ثوانٍ أو تبقى تعمل أيامًا.
أما الخدمة (Service) — وتُسمّى أحيانًا daemon أو "خفيّ" — فهي برنامج مُصمّم ليعمل في الخلفية بشكل دائم دون تدخّل مباشر منك، ويبدأ غالبًا تلقائيًا عند إقلاع النظام. خادم Nginx خدمة، وقاعدة بيانات MySQL خدمة، وخادم SSH نفسه (sshd) خدمة. الخدمة في جوهرها عملية (أو مجموعة عمليات) لكن يُديرها النظام نيابةً عنك: يشغّلها، يراقبها، ويعيد تشغيلها إن انهارت.
العلاقة بينهما هرمية: حين تشغّل خدمة Nginx، يخلق systemd عملية رئيسية (master) قد تتفرّع منها عمليات عاملة (workers). إدارة الخدمة تعني إدارة دورة حياتها عالية المستوى (تشغيل/إيقاف/تمكين)، بينما إدارة العملية تعني التعامل مع نسخة جارية بعينها (مراقبتها أو إنهائها أو خفض أولويّتها).
| المفهوم | تعريفه | كيف تتعامل معه | مثال |
|---|---|---|---|
| العملية (Process) | برنامج قيد التنفيذ، له PID | ps، top، kill | أمر tar يضغط ملفًا الآن |
| الخدمة (Service/daemon) | عملية خلفية دائمة يديرها النظام | systemctl، journalctl | Nginx، MySQL، sshd |
| الوحدة (Unit) | تعريف systemd لمورد قابل للإدارة | ملفات .service، .timer | nginx.service |
| الإشارة (Signal) | رسالة قصيرة تُرسَل لعملية لتوجيهها | kill، pkill | SIGTERM، SIGKILL |
استيعاب هذا التمييز يوفّر عليك أخطاءً مكلفة. مثلًا، "قتل" عملية Nginx العاملة بـkill قد يجعل systemd يعيد تشغيلها فورًا (لأنه مُكلَّف بإبقائها حيّة)، بينما الطريقة الصحيحة لإيقافها فعلًا هي عبر الخدمة بـsystemctl stop.
ما هو systemd ولماذا يهيمن على Linux
systemd هو أول عملية تعمل عند إقلاع نظام Linux الحديث؛ يحمل دائمًا الرقم PID 1، وهو "الأب" لكل العمليات الأخرى. مهمته الأساسية تشغيل النظام (init system): يقرّر ماذا يُشغَّل وبأي ترتيب وكيف يُدار طوال حياة السيرفر. حلّ systemd محلّ النظام القديم SysVinit في معظم التوزيعات الكبرى منذ نحو 2015، وأصبح اليوم المعيار الفعلي على Ubuntu وDebian وCentOS وAlmaLinux وRocky Linux وFedora وopenSUSE.
سبب هيمنته أنه أكثر من مجرد مُقلِع: إنه إطار متكامل لإدارة الموارد. يتعامل مع كل شيء عبر مفهوم موحّد اسمه الوحدة (Unit)، وهي ملف نصّي يصف موردًا قابلًا للإدارة. أنواع الوحدات متعددة، لكن أهمها للمشغّل اليومي:
| نوع الوحدة | الامتداد | الغرض |
|---|---|---|
| service | .service | خدمة أو daemon (الأكثر استخدامًا) |
| socket | .socket | منفذ شبكة أو socket يُفعِّل خدمة عند الطلب |
| timer | .timer | جدولة تشغيل وحدة (بديل عصري لـcron) |
| target | .target | مجموعة وحدات تمثّل حالة نظام (مثل multi-user) |
| mount | .mount | نقطة ربط نظام ملفات |
| path | .path | تشغيل وحدة عند تغيّر ملف/مجلد |
ميزات systemd التي تهمّك مباشرةً: تشغيل الخدمات بالتوازي (إقلاع أسرع)، إعادة تشغيل تلقائية للخدمات المنهارة، تسجيل مركزي موحّد عبر journald، وإدارة دقيقة للاعتماديات (لا تبدأ خدمة قاعدة البيانات قبل أن تكون الشبكة جاهزة). كل أمر تكتبه بـsystemctl هو في الحقيقة حوار مع هذا المدير المركزي.
ملاحظة عن التوزيعات القديمة: بعض الأنظمة العتيقة جدًا أو الحاويات المُجرّدة قد لا تستخدم systemd (تعتمد OpenRC أو SysVinit). لكن أي VPS تجاري حديث على Ubuntu 20.04+ أو Debian 11+ أو AlmaLinux 8+ يأتي بـsystemd افتراضيًا، وهو ما نفترضه طوال هذا الدليل.
حالات الخدمة وأمر systemctl status
كل خدمة في systemd تكون في حالة محدّدة في أي لحظة. فهم هذه الحالات هو نقطة البداية في أي تشخيص، لأن السؤال الأول دائمًا: "هل الخدمة تعمل أصلًا؟". الأمر الذي يجيب عن ذلك هو systemctl status:
systemctl status nginx
سيعرض لك مخرجًا غنيًا: السطر الأول يحمل الحالة الإجمالية (مثل active (running))، يتبعه ما إذا كانت الخدمة مُمكَّنة عند الإقلاع، ومتى بدأت، ورقم العملية الرئيسية (Main PID)، واستهلاك الذاكرة، وآخر بضعة أسطر من سجلّها. هذا المخرج وحده يكفي غالبًا لتشخيص 80% من المشكلات.
الحالات التي ستراها في حقل Active:
| الحالة | معناها | ماذا تفعل |
|---|---|---|
active (running) | الخدمة تعمل الآن بشكل طبيعي | لا شيء، كل شيء سليم |
active (exited) | نُفِّذت مرة وانتهت بنجاح (مهمة لمرة واحدة) | طبيعي لخدمات الإعداد |
active (waiting) | تعمل لكنها تنتظر حدثًا (socket مثلًا) | طبيعي |
inactive (dead) | متوقّفة، لا تعمل | شغّلها إن احتجتها |
failed | حاولت العمل لكنها انهارت أو خرجت بخطأ | اقرأ السجلّ فورًا |
activating | في طور البدء حاليًا | انتظر لحظة ثم تحقّق |
deactivating | في طور الإيقاف | انتظر اكتمال الإيقاف |
التمييز الأهم هنا بين inactive وfailed. الأولى تعني أن الخدمة متوقّفة بهدوء (ربما لأنك أوقفتها أو لم تبدأ أصلًا)، بينما failed تعني أنها حاولت العمل وفشلت — وهذه إشارة حمراء تستدعي قراءة السجلّ. لا تخلط بين أن خدمة "مُمكَّنة" (enabled) وأنها "تعمل" (active): التمكين يعني أنها ستبدأ تلقائيًا عند الإقلاع التالي، لكنه لا يشغّلها الآن. خدمة قد تكون enabled وinactive في الوقت نفسه (مُمكَّنة لكن النظام لم يُعَد إقلاعه بعد، أو أوقفتها يدويًا).
دورة حياة الخدمة تنتقل بين هذه الحالات عبر أوامر systemctl: من inactive إلى active عبر start، والعكس عبر stop، ومن active إلى active (إعادة) عبر restart. إن انهارت أثناء عملها انتقلت إلى failed، ومنها تعود إلى active بأمر restart بعد إصلاح السبب — أو بـreset-failed لمسح علامة الفشل دون تشغيل.
أوامر systemctl الأساسية
systemctl هو سكّينك السويسري لإدارة الخدمات. تعلّم حفنة أوامر منه تكفي لتشغيل سيرفر كامل. إليك المرجع الذي ستعود إليه دائمًا:
| الأمر | ماذا يفعل |
|---|---|
systemctl start nginx | يشغّل الخدمة الآن (لا يؤثّر على الإقلاع) |
systemctl stop nginx | يوقف الخدمة الآن |
systemctl restart nginx | يوقفها ثم يشغّلها (تطبيق تغييرات جذرية) |
systemctl reload nginx | يعيد قراءة الإعدادات دون إيقاف (لا يقطع الاتصالات) |
systemctl reload-or-restart nginx | يعيد التحميل إن أمكن، وإلا يعيد التشغيل |
systemctl status nginx | يعرض حالتها التفصيلية وآخر السجلّ |
systemctl enable nginx | يجعلها تبدأ تلقائيًا عند الإقلاع |
systemctl disable nginx | يلغي بدءها التلقائي عند الإقلاع |
systemctl enable --now nginx | يمكّنها ويشغّلها الآن في أمر واحد |
systemctl disable --now nginx | يعطّلها ويوقفها الآن في أمر واحد |
systemctl is-active nginx | يطبع active أو inactive فقط (مفيد للسكربتات) |
systemctl is-enabled nginx | يطبع enabled أو disabled |
systemctl mask nginx | يمنع تشغيلها كليًا حتى يدويًا (قفل صارم) |
systemctl unmask nginx | يرفع القفل |
systemctl daemon-reload | يعيد قراءة ملفات الوحدات بعد تعديلها |
الفرق بين restart وreload يستحق وقفة، لأنه أكثر ما يُساء فهمه. restart يقتل العملية بالكامل ويبدأ من الصفر — وهذا يقطع كل الاتصالات الجارية لثوانٍ. أما reload فيرسل إشارة للخدمة لتعيد قراءة ملف إعداداتها دون إيقاف، فتبقى الاتصالات الحالية حيّة. القاعدة العملية: لتغييرات الإعداد البسيطة (مثل إضافة موقع جديد في Nginx) استخدم reload؛ ولترقية البرنامج نفسه أو تغييرات جوهرية استخدم restart. لكن انتبه: ليست كل الخدمات تدعم reload، ولذلك يوجد reload-or-restart الذي يختار الأنسب تلقائيًا.
لرؤية كل الخدمات وحالاتها دفعةً واحدة:
systemctl list-units --type=service
ولرؤية الخدمات المُمكَّنة عند الإقلاع فقط:
systemctl list-unit-files --type=service --state=enabled
ولعرض الخدمات الفاشلة وحدها — وهو أول ما أفحصه عند أي مشكلة:
systemctl --failed
التمكين عند الإقلاع: الفرق الجوهري
نقطة يخطئ فيها المبتدئون كثيرًا: تشغيل خدمة بـstart لا يجعلها تبدأ بعد إعادة الإقلاع. لو أعدت تشغيل السيرفر، ستجد موقعك معطّلًا لأنك نسيت enable. القاعدة الذهبية لأي خدمة إنتاجية: استخدم دائمًا enable --now لتضمن أنها تعمل الآن وستعمل بعد كل إقلاع:
systemctl enable --now nginx
والعكس صحيح: خدمة لا تحتاجها يجب أن تُعطَّل بـdisable --now لتحرير الموارد ومنعها من البدء عند الإقلاع. لكن احذر من تعطيل خدمات لا تعرف وظيفتها — تعطيل خدمة نظامية حيوية (مثل خدمة الشبكة أو إدارة السجلّات) قد يجعل سيرفرك غير قابل للوصول بعد الإقلاع التالي. القاعدة: لا تعطّل ما لا تفهمه.
تحتاج موارد مخصّصة وتحكّمًا كاملًا؟
خطط VPS من wpressly بموارد مضمونة وصلاحية root، مُدارة وغير مُدارة، مع دعم عربي للإعداد والتأمين من اليوم الأول.
استعرض خطط VPSقراءة السجلّات بـjournalctl
حين تفشل خدمة، السؤال التالي مباشرةً هو "لماذا؟"، والجواب دائمًا في السجلّات. في عالم systemd، تُجمَّع كل سجلّات الخدمات في نظام تسجيل مركزي اسمه journald، وتُقرَأ بأمر journalctl. هذا أحد أقوى أدوات التشخيص، وإتقانه يختصر ساعات من البحث.
أبسط استخدام هو قراءة سجلّ خدمة محدّدة بخيار -u (unit):
journalctl -u nginx
لكن السجلّ قد يكون ضخمًا. الأكثر فائدةً في الواقع العملي هو متابعة السجلّ مباشرةً (live) أثناء حدوث المشكلة، بإضافة -f (follow) — تمامًا كما تشاهد شريط أحداث متجدّدًا:
journalctl -u nginx -f
اترك هذا الأمر يعمل في نافذة، ثم أعد تشغيل الخدمة أو أرسل طلبًا للموقع في نافذة أخرى، وراقب الأخطاء تظهر لحظيًا. هذه أسرع طريقة لربط فعل معيّن بالخطأ الناتج عنه.
مرجع أهم خيارات journalctl:
| الخيار | ماذا يفعل |
|---|---|
-u nginx | يقصر السجلّ على وحدة محدّدة |
-f | يتابع السجلّ مباشرةً (live tail) |
-b | سجلّ الإقلاع الحالي فقط |
-b -1 | سجلّ الإقلاع السابق |
-p err | الأخطاء فقط (priority = error فأعلى) |
-n 50 | آخر 50 سطرًا فقط |
--since "1 hour ago" | منذ ساعة |
--since today | منذ بداية اليوم |
--since "2026-06-13 09:00" | منذ توقيت محدّد |
-r | عكس الترتيب (الأحدث أولًا) |
-k | رسائل النواة (kernel) فقط — مثل dmesg |
--no-pager | بلا صفحات، للنسخ والسكربتات |
--disk-usage | حجم السجلّات على القرص |
أمثلة عملية شائعة. لرؤية كل الأخطاء منذ آخر إقلاع — أول ما أفحصه عند سلوك غريب للنظام:
journalctl -p err -b
ولفحص ما حدث لخدمة في آخر ساعة فقط، فتُركّز على الفترة المهمّة:
journalctl -u mysql --since "1 hour ago"
مستويات الأولوية في -p تتدرّج من الأخطر للأقل: emerg ثم alert ثم crit ثم err ثم warning ثم notice ثم info ثم debug. حين تكتب -p err فأنت تطلب كل ما هو بمستوى err فأعلى خطورة.
إدارة حجم السجلّات
journald يحتفظ بالسجلّات على القرص، وقد تنمو بمرور الوقت حتى تلتهم مساحة معتبرة على VPS محدود التخزين. لفحص الحجم الحالي:
journalctl --disk-usage
ولتقليصها — مثلًا إبقاء آخر 200 ميغابايت فقط أو حذف الأقدم من أسبوعين:
sudo journalctl --vacuum-size=200M
sudo journalctl --vacuum-time=2weeks
للضبط الدائم، عدّل /etc/systemd/journald.conf واضبط SystemMaxUse=200M، ثم أعد تشغيل خدمة journald. هذه خطوة صغيرة لكنها تنقذك من امتلاء القرص فجأةً، وهو سبب شائع لتعطّل سيرفرات لم تُراقَب جيدًا. مراقبة المساحة بشكل منهجي جزء أساسي من مراقبة سيرفر VPS.
مراقبة العمليات: ps وtop وhtop وfree
ننتقل الآن من الخدمات (المستوى العالي) إلى العمليات (المستوى المنخفض). حين يبطؤ سيرفرك أو يستهلك ذاكرته بالكامل، تحتاج لرؤية ما يجري فعليًا: أي عملية تلتهم المعالج أو الذاكرة؟ هنا تدخل أدوات المراقبة.
الأداة الفورية: ps
ps يلتقط "صورة" لحظية للعمليات الجارية. الصيغة الأكثر استخدامًا هي ps aux التي تعرض كل العمليات لكل المستخدمين:
ps aux
أعمدة المخرج المهمة: USER (المالك)، PID (الرقم التعريفي)، %CPU و%MEM (النسب المئوية للاستهلاك)، STAT (حالة العملية)، وCOMMAND (الأمر الكامل). القوة الحقيقية لـps تظهر مع الفرز. لإيجاد أكثر عشر عمليات استهلاكًا للذاكرة — سؤال شائع جدًا عند نفاد الـRAM:
ps aux --sort=-%mem | head
وللمعالج بدل الذاكرة، بدّل المفتاح إلى -%cpu:
ps aux --sort=-%cpu | head
علامة الناقص قبل %mem تعني الترتيب تنازليًا (الأكبر أولًا)، وhead يقتطع أعلى عشرة فقط. هذان الأمران من أكثر ما ستكرّره عمليًا.
الأداة الحيّة: top
بينما ps صورة جامدة، top لوحة متجدّدة كل ثانيتين تُظهر النظام وهو يتنفّس:
top
السطر الأعلى يعرض load average (سنشرحه بعد قليل)، تلاه ملخّص للذاكرة والمعالج، ثم قائمة العمليات مرتّبة افتراضيًا حسب استهلاك المعالج. داخل top يمكنك الضغط على M للفرز حسب الذاكرة، P للمعالج، k لإرسال إشارة قتل لعملية، وq للخروج. إنها أداة تأتي مثبّتة على كل توزيعة تقريبًا، فلا اعتماديات إضافية.
الأداة المفضّلة: htop
htop هو top لكن بواجهة أجمل وأسهل بكثير: ألوان، أشرطة استخدام لكل نواة معالج، تمرير أفقي وعمودي بالأسهم، وإنهاء عمليات بضغطة زر دون حفظ الـPID. لا يأتي مثبّتًا دائمًا، فثبّته أولًا:
sudo apt install htop # على Ubuntu/Debian
sudo dnf install htop # على AlmaLinux/CentOS/RHEL
htop
داخل htop: السهمان يتنقّلان بين العمليات، F6 للفرز حسب عمود، F9 لإرسال إشارة (قتل)، F5 لعرض شجري يُظهر علاقات الأب والابن بين العمليات، وF10 أو q للخروج. لمعظم المستخدمين، htop هو الأداة اليومية المفضّلة لمراقبة الموارد بصريًا.
الذاكرة: free
لرؤية حالة الذاكرة وحدها بوضوح، استخدم free مع -h (human-readable) ليعرض الأرقام بوحدات مقروءة:
free -h
ستظهر أعمدة: total (الذاكرة الكلية)، used (المستخدمة)، free (الحرّة)، وavailable (المتاحة فعليًا للتطبيقات الجديدة). نقطة مهمّة كثيرًا ما تُربك المبتدئين: لا تفزع إذا رأيت free منخفضًا جدًا. Linux يستخدم الذاكرة الفائضة كـcache لتسريع القرص، لكنه يحرّرها فورًا عند الحاجة. العمود الذي يهمّك حقًا هو available لا free.
| الأداة | النوع | الميزة | متى تستخدمها |
|---|---|---|---|
ps | لقطة جامدة | سريع، قابل للفرز والسكربتة | استعلام سريع أو داخل سكربت |
top | حيّ متجدّد | مثبّت في كل مكان، لا اعتماديات | مراقبة سريعة حين لا htop |
htop | حيّ تفاعلي | ألوان، شجرة، إنهاء سهل | المراقبة البصرية اليومية |
free | لقطة للذاكرة | تركيز على الـRAM والـswap | فحص ضغط الذاكرة |
فهم load average
في أعلى مخرج top وhtop وuptime ستجد ثلاثة أرقام مثل 0.52, 0.43, 0.38. هذا هو load average: متوسط عدد العمليات التي تنتظر المعالج (أو تستخدمه) خلال آخر دقيقة، خمس دقائق، وخمس عشرة دقيقة على التوالي. القراءة بسيطة لكنها حاسمة: قارن الرقم بعدد أنوية المعالج.
إن كان لسيرفرك نواة واحدة، فإن load يساوي 1.0 يعني أن المعالج مشغول 100% دون انتظار (الحد المثالي). فوق 1.0 يعني أن عمليات تنتظر دورها (ازدحام). أما إن كان لديك 4 أنوية، فإن load يساوي 4.0 هو الحدّ الكامل، و2.0 يعني نصف الطاقة. لمعرفة عدد الأنوية:
nproc
القاعدة العملية: load average أقل من عدد الأنوية = صحّي، يساويه = على الحدّ، أعلى منه باستمرار = السيرفر مُحمَّل فوق طاقته وتحتاج لتحسين أو ترقية. النظر للأرقام الثلاثة معًا يكشف الاتجاه: لو الرقم الأول (الدقيقة) أعلى بكثير من الثالث (15 دقيقة) فالحمل يتصاعد الآن؛ والعكس يعني أن ذروةً عابرة تنحسر.
إنهاء العمليات والإشارات
أحيانًا تتجمّد عملية أو تستهلك موارد بجنون، فتحتاج لإنهائها. في Linux لا "نقتل" العمليات بالمعنى الفجّ، بل نرسل لها إشارات (signals) — رسائل قصيرة تطلب منها سلوكًا معيّنًا. الأداة الأساسية هي kill، واسمها مضلّل قليلًا لأنها في الحقيقة تُرسل أي إشارة، ليس القتل فقط.
أهم الإشارات التي ستستخدمها:
| الإشارة | الرقم | معناها | السلوك |
|---|---|---|---|
| SIGTERM | 15 | إنهاء مهذّب (الافتراضي) | تطلب من العملية الإغلاق بنظافة |
| SIGKILL | 9 | قتل فوري قسري | يُنهيها فورًا دون تنظيف |
| SIGHUP | 1 | إعادة قراءة الإعداد | تعيد تحميل الإعدادات غالبًا |
| SIGINT | 2 | مقاطعة | مكافئ Ctrl+C في الطرفية |
| SIGSTOP | 19 | إيقاف مؤقت | تجمّد العملية (لا يمكن تجاهلها) |
| SIGCONT | 18 | استئناف | يكمل عملية مُوقَفة بـSIGSTOP |
القاعدة الذهبية: ابدأ دائمًا بـSIGTERM. الأمر kill بلا خيار يرسل SIGTERM افتراضيًا، وهو يطلب من العملية أن تغلق نفسها بنظافة — تحفظ ملفاتها، تغلق اتصالاتها، ثم تخرج:
kill 1234
إن كانت العملية متجمّدة تمامًا ولا تستجيب لـSIGTERM، عندها فقط تلجأ إلى SIGKILL (الرقم 9)، وهو إنهاء قسري لا يمكن للعملية تجاهله ولا الاستجابة له بأناقة:
kill -9 1234
خطأ شائع خطير: الاندفاع إلى kill -9 كأنه الحل الافتراضي. SIGKILL لا يمنح العملية فرصة لحفظ بياناتها أو إغلاق ملفاتها، وقد يترك ملفات مؤقتة فاسدة أو قاعدة بيانات في حالة غير متّسقة. استخدمه ملاذًا أخيرًا فقط بعد أن يفشل SIGTERM، وانتظر بضع ثوانٍ بين المحاولتين لتعطي العملية فرصة الاستجابة.
القتل بالاسم: killall وpkill
أحيانًا لا تعرف الـPID لكنك تعرف اسم البرنامج. killall ينهي كل العمليات بالاسم الكامل، وpkill أكثر مرونةً إذ يقبل أنماطًا جزئية:
killall firefox # ينهي كل عمليات باسم firefox بالضبط
pkill -f "python script" # ينهي أي عملية يطابق سطر أمرها النمط
pkill -u www-data # ينهي كل عمليات المستخدم www-data
خيار -f في pkill يطابق سطر الأمر الكامل لا الاسم فقط، وهو مفيد لعمليات بايثون أو نود التي تحمل كلها الاسم العام python أو node. لكن احذر شدّةً هنا: نمط فضفاض في pkill قد ينهي عمليات لم تقصدها. القاعدة الوقائية: استخدم pgrep أولًا (نفس بناء pkill لكنه يطبع المطابقات فقط دون قتل) لتتأكد من أنك تستهدف ما تريد:
pgrep -fa "python script" # يعرض ما سيُقتل قبل أن تقتله
تذكّر التحذير الأهم من بداية الدليل: إن كانت العملية تابعة لخدمة systemd مُدارة (مثل Nginx)، فقتلها بـkill غالبًا غير مجدٍ لأن systemd سيعيد تشغيلها. الطريق الصحيح هو systemctl stop، لا مطاردة الـPID.
الأولويات: nice وrenice
ليست كل العمليات متساوية في الأهمية. عملية نسخ احتياطي ثقيلة لا ينبغي أن تُبطئ خادم الويب الذي يخدم زوّارك. هنا يدخل مفهوم الأولوية (niceness): قيمة تخبر مجدول النواة كم "لطيفة" العملية تجاه غيرها في مشاركة المعالج.
قيمة niceness تتراوح من -20 (أعلى أولوية، أنانية) إلى +19 (أدنى أولوية، إيثارية)، والافتراضي هو 0. منطق التسمية معكوس وقد يربك: كلما زادت القيمة (أكثر "لطفًا") قلّت الأولوية، لأن العملية "تتنازل" عن المعالج لغيرها.
| قيمة nice | الأولوية | المعنى العملي |
|---|---|---|
| -20 | الأعلى | تستحوذ على المعالج، نادرًا ما تُستخدم |
| -10 | عالية | لمهام حسّاسة للزمن |
| 0 | عادية | الافتراضي لكل العمليات |
| +10 | منخفضة | لمهام الخلفية غير المستعجلة |
| +19 | الأدنى | تعمل فقط حين لا يريد أحد المعالج |
لبدء عملية بأولوية منخفضة من البداية، استخدم nice (تتطلب القيم السالبة صلاحية root):
nice -n 15 tar -czf backup.tar.gz /var/www
هذا يشغّل أمر النسخ بأولوية +15، فلا يزاحم الخدمات المهمّة ويعمل بهدوء في الخلفية. أما لتغيير أولوية عملية تعمل بالفعل، فاستخدم renice مع الـPID:
renice -n 10 -p 1234
أو لكل عمليات مستخدم معيّن دفعةً واحدة:
sudo renice -n 10 -u backupuser
نصيحة خبير: خفض الأولوية (nice) للمهام الثقيلة الدورية — كالنسخ الاحتياطي وضغط السجلّات وفحص الفيروسات — عادةٌ ممتازة تحمي تجاوب سيرفرك تحت الضغط. وبالمقابل، رفع الأولوية (القيم السالبة) نادرًا ما يكون الحل الصحيح؛ الأفضل غالبًا معالجة سبب البطء أو ترقية الموارد بدل إجبار النواة على تفضيل عملية على حساب الباقي. لتأمين السيرفر تحت الحمل، راجع أيضًا ممارسات تحصين أمان VPS لمنع العمليات الخبيثة من استنزاف الموارد أصلًا.
تحتاج موارد مخصّصة وتحكّمًا كاملًا؟
خطط VPS من wpressly بموارد مضمونة وصلاحية root، مُدارة وغير مُدارة، مع دعم عربي للإعداد والتأمين من اليوم الأول.
استعرض خطط VPSكتابة وحدة systemd مخصّصة
حتى الآن أدرنا خدمات جاهزة. لكن قوة systemd الحقيقية تظهر حين تحوّل تطبيقك الخاص إلى خدمة مُدارة — تبدأ تلقائيًا، تُعاد عند الانهيار، وتُسجَّل في journald. هذا أنظف بكثير من تشغيل التطبيق بـnohup أو screen وتركه عشوائيًا.
لنفترض أن لديك تطبيق Node.js يستمع على منفذ. أنشئ ملف وحدة في /etc/systemd/system/:
sudo nano /etc/systemd/system/myapp.service
وضع فيه التعريف التالي:
[Unit]
Description=My Node.js Application
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/myapp
ExecStart=/usr/bin/node /var/www/myapp/server.js
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
لنفكّك هذا الملف، فكل سطر مقصود:
- [Unit] يصف الوحدة وعلاقاتها.
Descriptionنصّ يظهر فيstatus.After=network.targetيضمن ألا تبدأ خدمتك قبل جاهزية الشبكة. - [Service] قلب التعريف.
Type=simpleيعني أنExecStartهو العملية الرئيسية مباشرةً.Userيحدّد المستخدم الذي تعمل تحته الخدمة (لا تشغّلها كـroot إلا للضرورة — مبدأ الصلاحية الأدنى).WorkingDirectoryمجلد العمل.ExecStartالأمر الكامل بمسارات مطلقة.Restart=on-failureيجعل systemd يعيد تشغيلها تلقائيًا إن انهارت، وRestartSec=5ينتظر 5 ثوانٍ بين المحاولات.Environmentيمرّر متغيّرات بيئة. - [Install] يحدّد متى تُفعَّل عند
enable.WantedBy=multi-user.targetيعني أنها تبدأ في وضع التشغيل العادي متعدد المستخدمين.
بعد إنشاء الملف أو تعديله، يجب إخبار systemd بإعادة قراءة الوحدات، ثم تمكين الخدمة وتشغيلها:
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
sudo systemctl status myapp
خطأ شائع جدًا: نسيان daemon-reload بعد تعديل ملف الوحدة. systemd يخزّن نسخةً من التعريف في الذاكرة، فلن يرى تغييراتك حتى تُجبره على إعادة القراءة. إن عدّلت الملف وبدا وكأن التغيير لم يُطبَّق، فأول ما تفحصه هو هل نفّذت daemon-reload. خطأ آخر هو المسارات النسبية في ExecStart؛ systemd لا يفترض مجلد عمل، فاستخدم دائمًا مسارات مطلقة كاملة للبرنامج وملفاته.
قيم Restart تستحقّ معرفتها: no (لا إعادة)، on-failure (عند خروج بخطأ فقط — الأكثر شيوعًا)، always (دائمًا حتى عند الخروج الطبيعي)، وon-abnormal (عند الانهيار أو القتل بإشارة). لمعظم تطبيقات الويب on-failure هو الخيار المتوازن.
الجدولة: cron مقابل systemd timers
كثير من مهام السيرفر دورية: نسخ احتياطي ليلي، تنظيف ملفات مؤقتة، تجديد شهادات SSL. لجدولتها طريقتان: الكلاسيكية cron، والحديثة systemd timers.
cron الكلاسيكي
cron خدمة جدولة موجودة منذ عقود، بسيطة وموثوقة. تحرّر جدول مهامك بـ:
crontab -e
كل سطر مهمّة مكوّن من خمسة حقول زمنية يتبعها الأمر. الحقول الخمسة بالترتيب:
| الحقل | المدى | المعنى |
|---|---|---|
| الأول | 0-59 | الدقيقة |
| الثاني | 0-23 | الساعة |
| الثالث | 1-31 | يوم الشهر |
| الرابع | 1-12 | الشهر |
| الخامس | 0-7 | يوم الأسبوع (0 و7 = الأحد) |
الرمز * يعني "كل قيمة". مثال يشغّل سكربت نسخ احتياطي كل يوم الساعة 3:30 فجرًا:
30 3 * * * /usr/local/bin/backup.sh
أمثلة شائعة أخرى للأنماط: */15 * * * * كل 15 دقيقة، 0 * * * * كل ساعة في رأسها، 0 0 * * 0 كل أحد منتصف الليل، 0 2 1 * * أول كل شهر الساعة الثانية فجرًا. نصيحة عملية: وجّه مخرجات السكربت لملف سجلّ (>> /var/log/backup.log 2>&1) لأن cron يعمل صامتًا، فبدون ذلك لن تعرف إن فشلت المهمة.
systemd timers الحديثة
البديل العصري هو timers، وهي وحدات systemd تُشغّل خدمة في مواعيد محدّدة. تحتاج ملفين: خدمة (.service) تصف ما يُنفَّذ، ومؤقّت (.timer) يصف متى. أنشئ أولًا /etc/systemd/system/backup.service:
[Unit]
Description=Daily Backup Job
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
ثم المؤقّت /etc/systemd/system/backup.timer:
[Unit]
Description=Run backup daily at 3:30 AM
[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
[Install]
WantedBy=timers.target
OnCalendar يحدّد الموعد بصياغة systemd الزمنية (هنا: كل يوم 3:30 فجرًا). Persistent=true ميزة قوية: إن كان السيرفر مطفأً وقت الموعد، تُنفَّذ المهمة فور إقلاعه التالي بدل تفويتها — وهذا ما لا يفعله cron. فعّل المؤقّت (لاحظ أنك تمكّن الـ.timer لا الـ.service):
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers
أمر list-timers يعرض كل المؤقّتات ومتى ستعمل تاليًا — لوحة متابعة ممتازة. متى تختار أيًّا؟ المقارنة:
| المعيار | cron | systemd timer |
|---|---|---|
| البساطة | أبسط، سطر واحد | أعقد، ملفان |
| المهام الفائتة | تُفوَّت إن كان السيرفر مطفأً | تُنفَّذ لاحقًا مع Persistent |
| التسجيل | يدوي لملف | تلقائي في journald |
| الاعتماديات | لا يدعمها | يدعم After/Requires |
| المراقبة | لا أداة موحّدة | list-timers وstatus |
| الانتشار | في كل مكان | يحتاج systemd |
القاعدة العملية: لمهمة بسيطة سريعة، cron كافٍ ومألوف. لمهمة مهمّة تحتاج تسجيلًا موثوقًا، أو لا يجوز تفويتها، أو تعتمد على خدمات أخرى — اختر systemd timer. كلاهما صحيح؛ الاختيار حسب الأهمية والتعقيد.
تشخيص خدمة فاشلة: منهجية عملية
لنجمع كل ما سبق في سيناريو واقعي. زرت موقعك فوجدته معطّلًا. إليك المنهجية المنظّمة خطوةً خطوة بدل التخبّط.
الخطوة الأولى: افحص الحالة. ابدأ دائمًا بـstatus لتعرف أين تقف:
systemctl status nginx
إن رأيت failed، انتقل للسجلّ مباشرةً. الخطوة الثانية: اقرأ السبب. آخر أسطر status تلمّح، لكن السجلّ الكامل يفصح:
journalctl -u nginx -n 50 --no-pager
ابحث عن كلمات مثل error، failed، permission denied، أو address already in use. هذه تشير مباشرةً للسبب: خطأ في الإعداد، صلاحية مفقودة، أو منفذ مشغول بعملية أخرى.
الخطوة الثالثة: تحقّق من الإعداد قبل الإعادة. كثير من الخدمات توفّر فحصًا للإعداد. Nginx مثلًا:
sudo nginx -t
إن أبلغ عن خطأ في سطر معيّن، أصلحه قبل أي محاولة تشغيل — إعادة تشغيل خدمة بإعداد معطوب لن تنجح.
الخطوة الرابعة: ابحث عن تعارض المنافذ. لو كان الخطأ "address already in use"، اكتشف ما يحتلّ المنفذ:
sudo ss -tlnp | grep :80
الخطوة الخامسة: أعد التشغيل وراقب. بعد الإصلاح، أعد التشغيل وتابع السجلّ مباشرةً لتتأكد من نجاح البدء هذه المرة:
sudo systemctl restart nginx
journalctl -u nginx -f
إن عادت لحالة active (running) واستقرّت بضع ثوانٍ، فقد نجحت. أما إن بقيت تدخل حلقة فشل وإعادة، فالسبب لم يُحَل بعد، وعليك العودة للسجلّ بعمق أكبر. هذه المنهجية — حالة، سجلّ، إعداد، منفذ، إعادة مع مراقبة — تحلّ الغالبية العظمى من أعطال الخدمات.
تحتاج موارد مخصّصة وتحكّمًا كاملًا؟
خطط VPS من wpressly بموارد مضمونة وصلاحية root، مُدارة وغير مُدارة، مع دعم عربي للإعداد والتأمين من اليوم الأول.
استعرض خطط VPSالأسئلة الشائعة
ما الفرق بين systemctl restart وreload؟
restart يوقف الخدمة كليًا ثم يبدؤها من جديد، فيقطع الاتصالات الجارية لثوانٍ ويطبّق أي تغيير مهما كان جذريًا. reload يطلب من الخدمة إعادة قراءة ملف إعداداتها دون إيقاف، فتبقى الاتصالات حيّة، لكنه يناسب فقط تغييرات الإعداد التي تدعم إعادة التحميل الساخنة. القاعدة: reload للتغييرات البسيطة، restart للترقيات والتغييرات الجوهرية.
خدمتي تعمل لكنها لا تبدأ بعد إعادة الإقلاع، لماذا؟
لأنك شغّلتها بـsystemctl start فقط، وهذا لا يجعلها دائمة. start يشغّلها في الجلسة الحالية فحسب، بينما enable هو ما يضيفها لقائمة البدء التلقائي عند الإقلاع. الحل: نفّذ systemctl enable --now nginx لتضمن أنها تعمل الآن وستعمل بعد كل إقلاع.
متى أستخدم kill -9 ومتى أتجنّبه؟
استخدمه ملاذًا أخيرًا فقط. ابدأ دائمًا بـkill العادي (يرسل SIGTERM) الذي يطلب من العملية الإغلاق بنظافة وحفظ بياناتها. إن بقيت متجمّدة ولم تستجب بعد ثوانٍ، عندها فقط استخدم kill -9 (SIGKILL) الذي ينهيها قسرًا. الإفراط في -9 قد يفسد ملفات أو يترك قواعد بيانات في حالة غير متّسقة لأنه لا يمنح العملية فرصة للتنظيف.
كيف أجد العملية التي تستهلك كل الذاكرة؟
استخدم ps aux --sort=-%mem | head لرؤية أعلى عشر عمليات استهلاكًا للذاكرة فورًا، أو افتح htop واضغط F6 للفرز حسب عمود MEM. تذكّر أن العمود المهمّ في free -h هو available لا free، لأن Linux يستخدم الذاكرة الفائضة كذاكرة تخزين مؤقت يحرّرها عند الحاجة.
عدّلت ملف وحدة systemd ولم يتغيّر شيء، ما السبب؟
لأنك لم تنفّذ sudo systemctl daemon-reload بعد التعديل. systemd يحتفظ بنسخة من تعريف الوحدة في الذاكرة، فلا يرى تعديلاتك على الملف حتى تُجبره على إعادة قراءة الوحدات. بعد daemon-reload، نفّذ systemctl restart للخدمة لتطبيق التعريف الجديد فعليًا على النسخة الجارية.
ماذا يعني load average وكيف أعرف أن سيرفري محمّل؟
هو متوسط عدد العمليات التي تستخدم المعالج أو تنتظره خلال آخر دقيقة وخمس وخمس عشرة دقيقة. قارنه بعدد الأنوية (تعرفه بـnproc): إن كان أقل من عدد الأنوية فالسيرفر صحّي، وإن كان أعلى منه باستمرار فهو محمّل فوق طاقته وتحتاج لتحسين الأداء أو ترقية الموارد. مقارنة الأرقام الثلاثة تكشف ما إذا كان الحمل يتصاعد أم ينحسر.
ما الفرق بين cron وsystemd timer وأيهما أختار؟
cron أبسط (سطر واحد) ومألوف وموجود في كل مكان، لكنه يفوّت المهام إن كان السيرفر مطفأً وقت الموعد ولا يسجّل تلقائيًا. systemd timer أعقد (يحتاج ملفين) لكنه يسجّل في journald، ويدعم تنفيذ المهام الفائتة عبر Persistent=true، ويتكامل مع اعتماديات الخدمات. اختر cron للمهام البسيطة، وtimer للمهام الحرجة التي لا يجوز تفويتها أو تحتاج تتبّعًا موثوقًا.
كيف أوقف خدمة نظامية بشكل صحيح بدل قتل عملياتها؟
لا تطارد الـPID بـkill، لأن systemd سيعيد تشغيل الخدمة فورًا بحكم أنه مُكلَّف بإبقائها حيّة. الطريق الصحيح هو systemctl stop nginx لإيقافها مؤقتًا، أو systemctl disable --now nginx لإيقافها ومنعها من البدء عند الإقلاع. ولمنع تشغيلها كليًا حتى يدويًا استخدم systemctl mask، ولرفع القفل unmask.