مختبر 8.5 - تمرين إضافي: إنشاء 3 خدمات جديدة لـ Wiki.js واختبار طرق مختلفة لإيقافها
الأهداف
في نهاية هذا المختبر، ستكون قادرًا على:
- إتقان إنشاء مثيلات إضافية باستخدام قالب systemd (
wikijs@.service) - مقارنة عدة أوامر "لإيقاف التشغيل" وتحديد تلك التي تعمل بشكل صحيح (ولماذا)
- استخدام قوالب systemd لإدارة مثيلات متعددة لتطبيق واحد
- تحديد وإيقاف عمليات Node.js بطرق مختلفة
- فهم الفروقات بين
stop،disable،kill، وطرق الإيقاف الأخرى
المتطلبات المسبقة
- تثبيت Ubuntu 24.04
- الوصول إلى sudo/root
- تثبيت Wiki.js بالفعل (على الأقل مثيل واحد)
- معرفة أساسية بـ systemd و MariaDB
- فتح الطرفية
نظرة عامة
في هذا المختبر، ستقوم بإنشاء 3 مثيلات جديدة لـ Wiki.js (stage، qa، demo) باستخدام قالب systemd. بعد ذلك، ستختبر طرقًا مختلفة لإيقاف هذه الخدمات وستفهم لماذا تعمل بعض الطرق بينما لا تعمل الأخرى.
هيكلية المثيلات:
| البيئة | حساب Linux | المجلد | المنفذ | قاعدة بيانات MariaDB |
|---|---|---|---|---|
| stage | wikijs_stage | /var/www/stage.site1 | 3003 | wikidb_stage |
| qa | wikijs_qa | /var/www/qa.site1 | 3004 | wikidb_qa |
| demo | wikijs_demo | /var/www/demo.site1 | 3005 | wikidb_demo |
الجزء 1: إعداد قالب systemd
الخطوة 1: إنشاء قالب systemd
إذا لم يكن لديك قالب بالفعل، قم بإنشائه:
sudo nano /etc/systemd/system/wikijs@.service
محتوى القالب:
[Unit]
Description=Wiki.js Instance %i
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/node server
Restart=always
User=wikijs_%i
Environment=NODE_ENV=production
WorkingDirectory=/var/www/%i.site1
[Install]
WantedBy=multi-user.target
التفسير:
%iيتم استبداله بالمثيل (stage، qa، demo)wikijs_%iيصبحwikijs_stage،wikijs_qa،wikijs_demo/var/www/%i.site1يصبح/var/www/stage.site1، إلخ.
الخطوة 2: إعادة تحميل systemd
sudo systemctl daemon-reload
الجزء 2: إنشاء المثيلات الثلاث الجديدة
الخطوة 1: إنشاء المستخدمين النظاميين
# إنشاء المستخدمين لكل مثيل
sudo adduser --system --group wikijs_stage
sudo adduser --system --group wikijs_qa
sudo adduser --system --group wikijs_demo
# السماح بالاتصال باستخدام bash
sudo usermod -s /bin/bash wikijs_stage
sudo usermod -s /bin/bash wikijs_qa
sudo usermod -s /bin/bash wikijs_demo
الخطوة 2: إنشاء المجلدات
# إنشاء المجلدات لكل مثيل
sudo mkdir -p /var/www/stage.site1
sudo mkdir -p /var/www/qa.site1
sudo mkdir -p /var/www/demo.site1
# تحديد المالكين
sudo chown -R wikijs_stage:wikijs_stage /var/www/stage.site1
sudo chown -R wikijs_qa:wikijs_qa /var/www/qa.site1
sudo chown -R wikijs_demo:wikijs_demo /var/www/demo.site1
الخطوة 3: إنشاء قواعد بيانات MariaDB
# الاتصال بـ MariaDB
sudo mysql -u root -p
في shell MariaDB:
-- إنشاء قواعد البيانات
CREATE DATABASE wikidb_stage;
CREATE DATABASE wikidb_qa;
CREATE DATABASE wikidb_demo;
-- إنشاء المستخدمين
CREATE USER 'wikidb_stage_user'@'localhost' IDENTIFIED BY 'password_stage';
CREATE USER 'wikidb_qa_user'@'localhost' IDENTIFIED BY 'password_qa';
CREATE USER 'wikidb_demo_user'@'localhost' IDENTIFIED BY 'password_demo';
-- منح الامتيازات
GRANT ALL PRIVILEGES ON wikidb_stage.* TO 'wikidb_stage_user'@'localhost';
GRANT ALL PRIVILEGES ON wikidb_qa.* TO 'wikidb_qa_user'@'localhost';
GRANT ALL PRIVILEGES ON wikidb_demo.* TO 'wikidb_demo_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
الخطوة 4: تنزيل وتثبيت Wiki.js لكل مثيل
لـ Stage (المنفذ 3003)
# الاتصال كمستخدم wikijs_stage
sudo su - wikijs_stage
# الانتقال إلى المجلد
cd /var/www/stage.site1
# تنزيل Wiki.js
wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz
# استخراج
tar xzf wiki-js.tar.gz
# حذف الأرشيف
rm wiki-js.tar.gz
# نسخ ملف التكوين
cp config.sample.yml config.yml
# تحرير التكوين
nano config.yml
التكوين لـ stage:
port: 3003
bindIP: 0.0.0.0
db:
type: mariadb
host: localhost
port: 3306
user: wikidb_stage_user
pass: password_stage
db: wikidb_stage
ssl: false
احفظ واخرج. ثم:
exit
لـ QA (المنفذ 3004)
sudo su - wikijs_qa
cd /var/www/qa.site1
wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz
tar xzf wiki-js.tar.gz
rm wiki-js.tar.gz
cp config.sample.yml config.yml
nano config.yml
التكوين لـ qa:
port: 3004
bindIP: 0.0.0.0
db:
type: mariadb
host: localhost
port: 3306
user: wikidb_qa_user
pass: password_qa
db: wikidb_qa
ssl: false
احفظ واخرج. ثم:
exit
لـ Demo (المنفذ 3005)
sudo su - wikijs_demo
cd /var/www/demo.site1
wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz
tar xzf wiki-js.tar.gz
rm wiki-js.tar.gz
cp config.sample.yml config.yml
nano config.yml
التكوين لـ demo:
port: 3005
bindIP: 0.0.0.0
db:
type: mariadb
host: localhost
port: 3306
user: wikidb_demo_user
pass: password_demo
db: wikidb_demo
ssl: false
احفظ واخرج. ثم:
exit
الخطوة 5: تفعيل وبدء الخدمات
# تفعيل وبدء المثيلات الثلاث
sudo systemctl enable --now wikijs@stage
sudo systemctl enable --now wikijs@qa
sudo systemctl enable --now wikijs@demo
الخطوة 6: التحقق
# التحقق من حالة كل مثيل
sudo systemctl status wikijs@stage --no-pager
sudo systemctl status wikijs@qa --no-pager
sudo systemctl status wikijs@demo --no-pager
# التحقق من أن المنافذ قيد الاستماع
sudo ss -tlnp | grep -E '3003|3004|3005'
الجزء 3: تحديد العمليات والمنافذ
الملحق 1: أوامر لتحديد عمليات Node.js
1. عرض جميع عمليات Node مع وحدة systemd
ps -eo pid,user,unit,cmd | grep -w node
2. النسخة المختصرة: PID + سطر الأوامر
pgrep -a node
3. حلقة: لكل PID لـ Node، عرض المنافذ التي يستمع إليها
for pid in $(pgrep node); do lsof -Pan -p "$pid" -i; done
4. عرض جميع المقابس المفتوحة لـ Node مباشرة
ss -tlnp | grep node
5. لـ PID محدد
# استبدل 1234 بـ PID الحقيقي
systemctl status --pid=1234
cat /proc/1234/cgroup | grep system.slice
الجزء 4: اختبار طرق مختلفة للإيقاف
طرق الإيقاف للاختبار
الأمر A – إيقاف صحيح عبر systemd
# إيقاف نظيف للمثيل stage
sudo systemctl stop wikijs@stage
التحليل: هذا الأمر يوقف الخدمة بشكل نظيف عبر systemd. إنها الطريقة الموصى بها.
الأمر B – خطأ منطقي: تعطيل لاحقًا، لا يوقف
# تعطيل الخدمة ولكن لا يوقفها فورًا
sudo systemctl disable wikijs@qa
التحليل: هذا الأمر يعطل الخدمة عند بدء التشغيل ولكنه لا يوقفها إذا كانت قيد التشغيل بالفعل. تستمر الخدمة في العمل حتى إعادة التشغيل التالية.
الأمر C – ⚠️ خطير جدًا: قتل جميع العمليات "wikijs"
# قتل جميع العمليات المسماة "wikijs"
sudo killall wikijs
التحليل: هذا الأمر خطير لأنه يقتل جميع العمليات المطابقة للاسم، دون تمييز. يمكن أن يؤثر على عمليات أخرى غير ذات صلة.
الأمر D – إيقاف غير مباشر عبر منفذ المثيل Demo (3005)
# قتل العملية التي تستمع على المنفذ 3005
sudo fuser -k 3005/tcp
التحليل: هذا الأمر يحدد ويقتل العملية التي تستخدم المنفذ 3005. يعمل ولكن أقل نظافة من systemctl.
الأمر E – إيقاف قسري لـ QA (المنفذ 3004) عبر lsof + kill -9
# العثور على PID الذي يستمع على 3004 وقتله
sudo lsof -ti:3004 | xargs sudo kill -9
التحليل: هذا الأمر يعثر على PID للعملية التي تستمع على المنفذ 3004 ويقتلها بالقوة. يعمل ولكنه يستخدم SIGKILL (القوة الغاشمة).
الأمر F – إعادة تحميل ≠ إيقاف: لا يقطع الخدمة
# إعادة تحميل التكوين ولكن لا يقطع الخدمة
sudo systemctl reload wikijs@demo
التحليل: هذا الأمر يعيد تحميل تكوين الخدمة ولكنه لا يوقفها. تستمر الخدمة في العمل.
الإجابات الصحيحة فقط
الأوامر التي توقف الخدمات فعليًا هي:
# الأمر A - إيقاف نظيف
sudo systemctl stop wikijs@stage
# الأمر D - إيقاف عبر المنفذ
sudo fuser -k 3005/tcp
# الأمر E - إيقاف قسري عبر المنفذ
sudo lsof -ti:3004 | xargs sudo kill -9
التحقق من الإيقاف
# التحقق من عدم وجود خدمة نشطة
sudo systemctl status wikijs@stage
sudo systemctl status wikijs@qa
sudo systemctl status wikijs@demo
# رؤية ما إذا كانت المنافذ لا تزال قيد الاستماع
sudo ss -tlnp | grep node
# التحقق من عمليات Node.js
ps aux | grep node
الجزء 5: التمديد (اختياري)
إعادة تشغيل جميع المثيلات بشكل نظيف
# إعادة تشغيل جميع المثيلات في أمر واحد
sudo systemctl restart wikijs@{stage,qa,demo}
مراجعة جميع المنافذ النشطة لـ Node.js حاليًا
# رؤية جميع المنافذ التي يستمع إليها Node.js
sudo lsof -iTCP -sTCP:LISTEN | grep node
التحقق من أن جميع المنافذ تم تحريرها بعد الإيقاف
# إيقاف جميع المثيلات
sudo systemctl stop wikijs@{stage,qa,demo}
# التحقق من أن المنافذ خالية
sudo ss -tlnp | egrep '3003|3004|3005'
الملحق 2: أوامر مفيدة لإدارة الخدمات
1. رؤية جميع المنافذ النشطة والعمليات المرتبطة
| الأمر | التعليق / الهدف |
|---|---|
sudo ss -tuln | يعرض المنافذ المفتوحة TCP/UDP (الاستماع)، بدون حل DNS (سريع). |
sudo lsof -i -P -n | يعرض جميع المنافذ والبرامج التي تستخدمها. |
sudo lsof -i -P -n | grep node | يفلتر لرؤية عمليات Node.js فقط. |
sudo netstat -tulnp | الأمر القديم المكافئ لـ ss، يعرض أيضًا PID. |
sudo apt install net-tools | يثبت netstat (ضروري على Ubuntu الحديث). |
ps aux | grep node | يسرد جميع العمليات التي تحتوي على "node". |
sudo lsof -i :3000 | يعرض العملية التي تستمع تحديدًا على المنفذ 3000. |
sudo apt install nmap | يثبت nmap، ماسح للمنافذ. |
sudo nmap -sT -O localhost | يفحص المنافذ المفتوحة في TCP على الجهاز المحلي. |
2. إدارة خدمات Node.js باستخدام systemd
| الأمر | التعليق / الهدف |
|---|---|
systemctl | grep node | يبحث عن الخدمات التي تحتوي على "node". |
systemctl list-units --type=service | يسرد جميع الخدمات النشطة. |
ls /etc/systemd/system/ | يسرد الملفات .service المثبتة يدويًا. |
sudo systemctl stop nom-du-service | يوقف خدمة بشكل نظيف (مثل: wikijs.service). |
sudo systemctl disable nom-du-service | يمنع الخدمة من البدء في التمهيد التالي. |
sudo rm /etc/systemd/system/nom-du-service.service | يحذف ملف الخدمة. |
sudo systemctl daemon-reexec | يعيد تحميل systemd بالكامل. |
sudo systemctl daemon-reload | يعيد تحميل الملفات .service. |
systemctl list-units --type=service | grep -i node | يسرد خدمات Node.js (غير حساس لحالة الأحرف). |
systemctl list-units --type=service | grep 3100 | يبحث عن الخدمات المرتبطة بالمنفذ 3100. |
sudo systemctl reset-failed | يعيد تعيين حالة الخدمات الفاشلة. |
3. إيقاف عملية يدويًا (إذا لم تكن خدمة)
| الأمر | التعليق / الهدف |
|---|---|
sudo kill 1064738 | يحاول قتل العملية (PID 1064738) بشكل نظيف. |
sudo kill -9 1064738 | قتل العملية بالقوة (SIGKILL). |
ps -fp 1072723 | يعرض تفاصيل العملية 1072723 (صيغة موسعة). |
sudo ls -l /proc/1072723/exe | يعرض الملف التنفيذي الحقيقي الذي يتم تشغيله بواسطة العملية. |
sudo cat /proc/1072723/cmdline | tr '\0' ' ' | يعرض الأمر الدقيق الذي أطلق العملية. |
4. اكتشاف وإيقاف العمليات المدارة بواسطة PM2
| الأمر | التعليق / الهدف |
|---|---|
which pm2 | يتحقق مما إذا كان pm2 مثبتًا. |
pm2 list | يسرد التطبيقات المدارة بواسطة PM2. |
pm2 stop all | يوقف جميع تطبيقات PM2. |
pm2 delete all | يحذف جميع المراجع للتطبيقات. |
pm2 unstartup | يعطل بدء التشغيل التلقائي لـ PM2 عند التمهيد. |
5. إزالة كاملة لخدمة systemd
| الأمر | التعليق / الهدف |
|---|---|
ls /etc/systemd/system/ | grep -i wiki | يفلتر الملفات .service المرتبطة بـ "wiki". |
sudo systemctl stop wikijs.service | يوقف الخدمة قبل الإزالة. |
sudo systemctl disable wikijs.service | يعطل الخدمة. |
sudo rm /etc/systemd/system/wikijs.service | يحذف ملف الخدمة. |
sudo systemctl daemon-reload | يعيد تحميل تكوين systemd. |
sudo systemctl reset-failed | يعيد تعيين أخطاء systemd. |
systemctl list-units --type=service | grep wiki | يتحقق مما إذا كانت الخدمة قد اختفت. |
systemctl status wikijs.service | يتحقق مما إذا كانت الخدمة لا تزال موجودة. |
ls -l /etc/systemd/system/ | يسرد كامل للتحقق يدويًا. |
grep -r ExecStart /etc/systemd/system/ | يبحث عن أسطر التشغيل في جميع الخدمات. |
الملحق 3: قائمة شاملة بالأوامر
أوامر لرؤية المنافذ
sudo ss -tuln
sudo lsof -i -P -n
sudo lsof -i -P -n | grep node
sudo netstat -tulnp
sudo apt install net-tools
ps aux | grep node
sudo lsof -i :3000
sudo apt install nmap
sudo nmap -sT -O localhost
أوامر systemd
systemctl | grep node
systemctl list-units --type=service
ls /etc/systemd/system/
sudo systemctl stop nom-du-service
sudo systemctl stop wikijs.service
sudo systemctl disable nom-du-service
sudo rm /etc/systemd/system/nom-du-service.service
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
systemctl | grep 3100
systemctl | grep node
sudo systemctl stop wikijs.service
أوامر kill
sudo kill 1064738
sudo kill -9 1064738
sudo ss -tuln | grep 3100
sudo lsof -i :3100
أوامر PM2
which pm2 && pm2 list
pm2 stop all
pm2 delete all
pm2 unstartup
أوامر التشخيص
sudo systemctl list-units --type=service | grep -i node
ps aux | grep node
ps -fp 1072723
sudo ls -l /proc/1072723/exe
sudo cat /proc/1072723/cmdline | tr '\0' ' '
ls /etc/systemd/system/ | grep -i wiki
ls /lib/systemd/system/ | grep -i wiki
grep -r 3100 /etc/systemd/system/
أوامر الإزالة
sudo systemctl stop nom.service
sudo systemctl disable nom.service
sudo systemctl daemon-reload
sudo systemctl reset-failed
ls /etc/systemd/system/
ls /etc/systemd/system/ | grep -i wiki
sudo systemctl stop wikijs.service
sudo systemctl disable wikijs.service
sudo rm /etc/systemd/system/wikijs.service
sudo systemctl daemon-reload
sudo systemctl reset-failed
systemctl list-units --type=service | grep wiki
systemctl status wikijs.service
ls -l /etc/systemd/system/
grep -r ExecStart /etc/systemd/system/
تمارين عملية
تمرين 1: إنشاء وتشغيل المثيلات الثلاث
- قم بإنشاء المثيلات الثلاث (stage، qa، demo) باتباع الخطوات أعلاه
- تحقق من أن جميع المثيلات نشطة
- تحقق من أن المنافذ 3003، 3004، 3005 قيد الاستماع
تمرين 2: اختبار طرق الإيقاف
لكل طريقة إيقاف (A، B، C، D، E، F):
- أعد تشغيل المثيل المعني أولاً
- نفذ أمر الإيقاف
- تحقق مما إذا كانت الخدمة قد توقفت بالفعل
- وثق النتيجة في جدول
تمرين 3: مقارنة الطرق
أنشئ جدول مقارنة:
| الطريقة | الأمر | يعمل؟ | لماذا؟ | موصى به؟ |
|---|---|---|---|---|
| A | systemctl stop | ؟ | ؟ | ؟ |
| B | systemctl disable | ؟ | ؟ | ؟ |
| C | killall wikijs | ؟ | ؟ | ؟ |
| D | fuser -k port/tcp | ؟ | ؟ | ؟ |
| E | lsof -ti:port | xargs kill -9 | ؟ | ؟ | ؟ |
| F | systemctl reload | ؟ | ؟ | ؟ |
أسئلة للتفكير
-
لماذا
systemctl disableلا يوقف خدمة قيد التشغيل بالفعل؟- اشرح الفرق بين
stopوdisable
- اشرح الفرق بين
-
ما هي المخاطر من استخدام
killallلإيقاف الخدمات؟- قدم مثالًا لسيناريو يمكن أن يسبب مشاكل
-
لماذا
systemctl reloadلا يقطع الخدمة؟- اشرح الفرق بين
reloadوrestart
- اشرح الفرق بين
-
ما الفرق بين
killوkill -9؟- في أي حالات ستستخدم كل من هذه الأوامر؟
-
لماذا تستخدم قالب systemd (
wikijs@.service) بدلاً من إنشاء 3 ملفات خدمة منفصلة؟- ما هي المزايا والعيوب لكل نهج؟
ملخص طرق الإيقاف
الطرق الموصى بها ✅
systemctl stop wikijs@instance- إيقاف نظيف عبر systemdfuser -k port/tcp- إيقاف عبر المنفذ (يعمل ولكن أقل نظافة)lsof -ti:port \| xargs kill -9- إيقاف قسري (الملاذ الأخير)
الطرق التي يجب تجنبها ❌
systemctl disable- لا يوقف، يعطل فقط عند التمهيدsystemctl reload- يعيد تحميل التكوين ولكن لا يقطعkillall wikijs- خطير جدًا، يمكن أن يؤثر على عمليات أخرى
التحقق النهائي
تحقق من أنك قد نجحت في:
- إنشاء قالب systemd
wikijs@.service - إنشاء المستخدمين النظاميين الثلاثة (wikijs_stage، wikijs_qa، wikijs_demo)
- إنشاء المجلدات الثلاثة وتثبيت Wiki.js في كل منها
- إنشاء قواعد البيانات الثلاثة لـ MariaDB
- تكوين ملفات
config.ymlبالمنافذ الصحيحة - تفعيل وتشغيل المثيلات الثلاث
- التحقق من أن المنافذ 3003، 3004، 3005 قيد الاستماع
- اختبار جميع طرق الإيقاف
- فهم لماذا تعمل بعض الطرق بينما لا تعمل الأخرى
- الإجابة على أسئلة التفكير
الخطوات التالية
- مختبر 8.1: إدارة خدمات systemd (مراجعة)
- مختبر 8.2: خدمات مخصصة (تعمق)
- TP 2: Reverse Proxy NGINX (لكشف المثيلات عبر reverse proxy)
تم إنشاء المختبر في: ديسمبر 2024