هذا المقال لمستوى: مبتدئ.
systemd للمبتدئ: خلّي خدمتك ترجع لوحدها بعد أي كراش أو reboot
لو بتشغّل تطبيقك بأمر زي node app.js أو python app.py في التيرمنال، أول ما السيرفر يعمل reboot أو التطبيق يقع، الخدمة بتفضل واقعة لحد ما تدخل بإيدك تشغّلها. systemd بيحل ده: بيرجّع الخدمة لوحده في أقل من ثانية، وبيشغّلها تلقائيًا مع كل إقلاع.
المشكلة باختصار
الطريقة الشائعة إنك تفتح التيرمنال، تكتب أمر التشغيل، وتسيبه شغّال بـ & أو جوّه screen. الطريقة دي بتفشل في حالتين: أول reboot للسيرفر الخدمة مبتشتغلش، وأول كراش (خطأ في الكود أو نفاد ذاكرة) بتموت وتفضل ميتة. النتيجة downtime بيمتد لحد ما حد ياخد باله.
يعني إيه systemd؟ (بمثال بسيط الأول)
تخيّل موظف استقبال شغّال 24 ساعة. أول ما أي موظف تاني يسيب مكتبه أو يغمى عليه، الاستقبال بيرجّعه فورًا. systemd هو موظف الاستقبال ده، بس لكل الخدمات اللي على السيرفر.
علميًا: systemd هو نظام الإقلاع والإدارة (init system) في أغلب توزيعات Linux الحديثة. هو أول عملية بتشتغل بعد الـ kernel ورقمها PID 1. مهمته إنه يشغّل الخدمات (daemons)، يراقب حالتها، ويعيد تشغيلها حسب السياسة اللي بتحددها في ملف اسمه unit file. الـ unit file ببساطة وصفة بتقول: الخدمة اسمها إيه، تشغّلها بأي أمر، وتعمل إيه لو وقعت.
الحل: اكتب ملف خدمة واحد
هنعمل خدمة بتشغّل تطبيق Node وبترجع لوحدها لو وقعت. أنشئ الملف /etc/systemd/system/myapp.service:
[Unit]
Description=خدمة تطبيقي
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=5
[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/node /opt/myapp/server.js
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target
السطر المهم Restart=always: بيقول لـ systemd يرجّع الخدمة مهما كان سبب توقفها. وRestartSec=2 بيستنى ثانيتين قبل كل محاولة.
بعد كده شغّل الأوامر دي بالترتيب:
sudo systemctl daemon-reload # اقرأ ملفات الخدمات من جديد
sudo systemctl enable --now myapp # شغّلها دلوقتي وخليها تشتغل مع كل إقلاع
systemctl status myapp # اتأكد إنها active (running)
journalctl -u myapp -f # اقرأ اللوجز الحية
عايز تتأكد إن الرجوع التلقائي شغّال فعلًا؟ اقتل الخدمة بالعافية وشوف:
sudo systemctl kill -s KILL myapp
systemctl status myapp # هتلاقيها رجعت active خلال ثانيتين
الأرقام: الفرق الحقيقي
افترض إن خدمتك وقعت الساعة 3 الفجر. من غير systemd، بتفضل واقعة لحد ما حد يصحى ويلاحظ، يعني ممكن 5 ساعات downtime كاملة. مع Restart=always الخدمة بترجع في ثانيتين (والقيمة الافتراضية لـ RestartSec لو مسبتهاش فاضية هي 100 مللي ثانية). يعني نزّلت زمن التعافي (MTTR) من ساعات لثواني، من غير ما تكتب سطر كود واحد جوّه تطبيقك.
المقايضات (trade-offs)
الرجوع التلقائي مش سحر مجاني. لو تطبيقك بيقع بسبب باج حقيقي، Restart=always هيفضل يرجّعه فيدخل في حلقة (crash loop) تستهلك المعالج وتخفي المشكلة الأصلية. عشان كده حطينا StartLimitBurst=5 وStartLimitIntervalSec=60: لو الخدمة وقعت 5 مرات في 60 ثانية، systemd بيوقف المحاولات ويعلّمها failed بدل ما يفضل يلف. المكسب uptime وثبات. الثمن احتمال إخفاء أعطال لو مبتتابعش اللوجز.
متى لا تستخدم هذه الطريقة
هذا الشرح مبني على فرضية إنك على سيرفر Linux فيه systemd (Ubuntu 16.04+، Debian 8+، CentOS/RHEL 7+) وبتشغّل الخدمة مباشرة على النظام. لو تطبيقك جوّه Docker أو Kubernetes، متلفّهوش بـ systemd — المنسّق (orchestrator) بيتكفّل بإعادة التشغيل عبر restartPolicy أو الـ probes. وكمان لو السكربت بتاعك بيشتغل مرة واحدة وينتهي (مهمة قصيرة)، مش محتاج Restart=always؛ استخدم Type=oneshot أو timer بدلها.
الخطوة التالية
افتح السيرفر، انسخ ملف الخدمة فوق وعدّل ExecStart وWorkingDirectory على تطبيقك، ثم شغّل sudo systemctl enable --now myapp. بعدها اقتل العملية بـ systemctl kill -s KILL myapp وراقب systemctl status: لو رجعت active خلال ثواني، يبقى خدمتك بقت تحمي نفسها.
المصادر
- توثيق
systemd.serviceالرسمي (Restart، RestartSec، Type): freedesktop.org — systemd.service - توثيق
systemd.unit(StartLimitIntervalSec، StartLimitBurst، After، WantedBy): freedesktop.org — systemd.unit - الموقع الرسمي لمشروع systemd: systemd.io
- صورة غرفة الخوادم: Wikimedia Commons — BalticServers data center (CC BY-SA)
- صورة الطرفية: Wikimedia Commons — GNOME Terminal (CC BY-SA)