منابع آموزشی و پژوهشی، برای دانشگاه و مدرسه
پشتیبانیانتشار محتوا
دورهٔ آموزشیرایگان

آموزش لینوکس پیشرفته؛ مدیریت، امنیت و عیب‌یابی سرور

۱۶ درس در ۴ فصل۹ ساعت و ۵۴ دقیقهدربارهٔ دوره
۱. توزیع‌ها و سرویس‌هادرس ۳ از ۱۶

چرخه عمر یک سرویس کاربری با systemd

۴۰ دقیقه آموزش متنی

در این درس قرارداد اجرا را به unit تبدیل می‌کنیم تا وضعیت، شکست و تلاش دوباره قابل مشاهده باشد. پیش‌نیاز، Ubuntu آزمایشی با systemd و نشست کاربر عادی است؛ فرمان‌های مدیریتی با --user اجرا می‌شوند و sudo لازم نیست. اگر فرمان اول به bus کاربر وصل نشد، ادامه ندهید؛ از نشست واقعی روی VM دارای systemd استفاده کنید. تألیف: تحریریه درس‌آوند.

تفاوت چهار عملیات systemd: daemon-reload برای تعریف واحد، start برای اجرا، enable برای فعال‌سازی و status و journalctl برای مشاهده.
شروع سرویس، فعال‌سازی خودکار و خواندن دوبارهٔ تعریف واحد سه عملیات متفاوت‌اند. در تمرین دوره از نشست کاربری systemd استفاده می‌شود؛ این تصویر ترتیب اجباری اجرای همهٔ فرمان‌ها را نشان نمی‌دهد.
bash
systemctl --user show-environment >/dev/null
systemctl --version

Unit یک توصیف اعلانی از نحوه اجرا و سیاست نظارت است، نه رونوشت تاریخچه فرمان‌های ترمینال. Type=exec اجازه می‌دهد خطای آغاز اجرای باینری زودتر گزارش شود؛ اما active شدن آن تضمین آماده بودن منطق برنامه نیست. محیط سرویس نیز الزاماً متغیرها و مسیر کاری پوسته تعاملی شما را ندارد. مسیر کاری و مفسر را صریح می‌نویسیم. برنامه فقط پیام می‌نویسد و با یک نشانگر عمداً شکست می‌خورد.

bash
labdir=$(mktemp -d "$HOME/darsavand-linux2.XXXXXXXX")
unit="darsavand-$(basename "$labdir").service"
printf 'project=%s\nunit=%s\n' "$labdir" "$unit"

پوشه و نام unit یکتا هستند تا فایل موجودی بازنویسی نشود. نام چاپ‌شده را نگه دارید و مراحل این درس و درس لاگ را در همین ترمینال ادامه دهید؛ labdir و unit متغیر همان پوسته‌اند. فرمان بعد فایل worker.sh را در پوشه پروژه می‌سازد. اجرای مستقیم با مفسر انجام می‌شود؛ بنابراین نیازی به تغییر مجوز اجرای فایل نیست. فایل fail را فعلاً ایجاد نکنید تا اجرای سالم دیده شود.

bash
cat > "$labdir/worker.sh" <<'SH'
#!/bin/sh
printf '<6>worker started\n'
while :; do
  if [ -e ./fail ]; then
    printf '<3>planned failure: fail file exists\n' >&2
    exit 7
  fi
  printf '<6>heartbeat\n'
  sleep 5
done
SH

هر heartbeat نشان می‌دهد حلقه هنوز اجرا می‌شود؛ این جای بررسی سلامت واقعی یک سامانه را نمی‌گیرد. کد خروج ۷ در این برنامه قرارداد شکست آزمایشی است. پیشوند <6> سطح اطلاع‌رسانی و <3> سطح خطا را برای journal مشخص می‌کند؛ نوشتن روی stderr به‌تنهایی تضمین سطح err نیست. فایل unit زیر با مقادیر همین پروژه ساخته می‌شود. در فایل unit، ExecStart پوسته تعاملی نیست و نشانه‌هایی مثل pipe خودکار تفسیر نمی‌شوند.

bash
cat > "$labdir/$unit" <<EOF
[Unit]
Description=Darsavand user service lab
StartLimitIntervalSec=30
StartLimitBurst=3

[Service]
Type=exec
WorkingDirectory=$labdir
ExecStart=/bin/sh "$labdir/worker.sh"
Restart=on-failure
RestartSec=2
StandardOutput=journal
StandardError=journal
SyslogLevelPrefix=yes

[Install]
WantedBy=default.target
EOF

Restart=on-failure برای شکست تلاش دوباره می‌کند؛ stop عمدی سرویس این سیاست را فعال نمی‌کند. فاصله دوثانیه‌ای از حلقه بسیار سریع جلوگیری می‌کند. محدودیت سه آغاز در سی ثانیه برای مهار خطای تکرارشونده است؛ این شمارنده شروع دستی را هم دربرمی‌گیرد. این‌ها درمان علت خطا نیستند. بخش Install فقط رابطه پیشنهادی برای enable را تعریف می‌کند و وجودش به‌خودی‌خود سرویس را اجرا یا فعال‌سازی دائمی نمی‌کند. اکنون unit را پیوند می‌دهیم و اجرای موقت را آغاز می‌کنیم.

bash
systemd-analyze --user verify "$labdir/$unit"
systemctl --user link "$labdir/$unit"
systemctl --user daemon-reload
systemctl --user start "$unit"
systemctl --user status "$unit" --no-pager

در خروجی، Loaded بارگذاری فایل و Active معمولاً active (running) را نشان می‌دهد. verify بررسی ایستای تعریف است و موفقیتش تضمین اجرای درست نیست. پس از ویرایش خود unit، daemon-reload لازم است؛ برای اعمال رفتار جدید روی فرایند جاری معمولاً restart نیز لازم می‌شود. reload برای بازخوانی تنظیمات داخلی برنامه است و این سرویس آن را پیاده نکرده است. enable از start مستقل است؛ این آزمایشگاه سرویس را enable نمی‌کند و ماندگاری پس از خروج کاربر یا بوت را وعده نمی‌دهد.

تمرین: فایل fail را بسازید و پیش‌بینی کنید آیا سرویس تا ابد هر دو ثانیه برمی‌گردد. پیش از اجرای فرمان‌ها حدس خود را بنویسید. دوازده ثانیه برای مشاهده در نظر گرفته شده؛ زمان‌بندی دقیق به میزبان وابسته است. اگر هنوز در حالت auto-restart بود، چند لحظه بعد وضعیت را دوباره بخوانید. این آزمایش فقط فایل نشانگر داخل پروژه و سرویس یکتای خودتان را تغییر می‌دهد.

bash
touch "$labdir/fail"
sleep 12
systemctl --user show "$unit" -p ActiveState -p SubState -p Result -p NRestarts

پاسخ: وجود نشانگر، هر اجرای تازه را هم با خطا خارج می‌کند؛ سیاست محدودیت آغاز سرانجام ادامه تلاش را متوقف می‌کند. معمولاً ActiveState=failed و Result=start-limit-hit دیده می‌شود، اما مقدار لحظه‌ای و شمار تلاش‌ها را باید از همان ماشین خواند. حذف نشانگر علت آزمایشی را رفع می‌کند؛ پاک‌کردن وضعیت failed علت را رفع نمی‌کند. پروژه را برای بررسی شواهد در درس بعد نگه دارید. اگر ادامه نمی‌دهید، بلوک پاک‌سازی زیر فقط فایل‌های همین پروژه را حذف می‌کند؛ پیش از اجرا درست بودن متغیرها و مسیر چاپ‌شده را بررسی کنید.

bash
systemctl --user disable --now "$unit"
rm -- "$labdir/worker.sh" "$labdir/$unit"
rm -f -- "$labdir/fail"
rmdir -- "$labdir"
systemctl --user daemon-reload
unset labdir unit

منابع رسمی انگلیسی:
systemd service: https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html
systemd unit and start limits: https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html
systemctl lifecycle: https://www.freedesktop.org/software/systemd/man/latest/systemctl.html
Execution environment: https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html

ورود برای ثبت پیشرفت

متن درس‌های عمومی را بدون ورود بخوانید.

یادگیری‌ات را دنبال کن

برای نگهداری پیشرفت و ادامهٔ یادگیری از حساب خود استفاده کن.

ورود و ثبت‌نام
دربارهٔ این دوره

دورهٔ دوم و رایگان لینوکس با ۱۶ درس عملی؛ مقایسهٔ توزیع‌ها، systemd، امنیت، شبکه، کانتینر، Ansible و بازیابی. ادامهٔ دورهٔ مقدماتی درس‌آوند.

پرسشی دربارهٔ این درس داری؟گفت‌وگو با پشتیبانی در حساب کاربری
یکجا انتخاب کن، راحت‌تر دریافت کن

انتخاب‌های من ۰ منبع

مجموعهٔ مطالعه‌ات را بساز.

کنار مقاله‌ها «انتخاب» را بزنید تا چند فایل را با هم دریافت کنید.

انتخاب مقاله‌های رایگان