ESC را فشار دهید تا بسته شود

systemd Timer چیست؟ آموزش جایگزینی Cron در سرور لینوکس

فهرست

systemd Timer ابزار زمان‌بندی داخلی systemd است که در سرورهای لینوکسی می‌تواند بسیاری از Cron Jobها را با کنترل بهتر، لاگ یکپارچه و امکان جبران اجرای از‌دست‌رفته جایگزین کند. در این روش، فایل .timer تعیین می‌کند کار چه زمانی اجرا شود و فایل .service مشخص می‌کند چه دستوری اجرا شود.

خلاصه سریع: اگر فقط یک زمان‌بندی ساده و قابل‌حمل بین سیستم‌های یونیکسی می‌خواهید، Cron هنوز انتخاب خوبی است. اگر سرور شما systemd دارد و به لاگ شفاف، وابستگی سرویس‌ها، Persistent=true، زمان‌بندی بر اساس بوت یا پراکندگی بار نیاز دارید، systemd Timer معمولاً انتخاب قوی‌تری است.

systemd Timer چیست و چه تفاوتی با Cron دارد؟

Timer یکی از انواع unitهای systemd است. برخلاف Cron که زمان و فرمان اجرا را معمولاً در یک خط crontab می‌نویسیم، systemd مسئولیت «چه زمانی» و «چه کاری» را جدا می‌کند. این جداسازی باعث می‌شود وضعیت اجرا، خطاها و وابستگی‌ها راحت‌تر مدیریت شوند. اگر با خود systemd آشنا نیستید، ابتدا مقاله بررسی systemd و سرویس‌منیجمنت مدرن را ببینید.

ویژگیCronsystemd Timer
سادگی تنظیمبسیار سادهدو unit جداگانه
لاگوابسته به تنظیم خروجی/syslogیکپارچه با journal
اجرای از‌دست‌رفتهبه‌صورت پیش‌فرض خیربا Persistent=true برای timer تقویمی
زمان نسبت به بوتمحدودOnBootSec و گزینه‌های monotonic
وابستگی سرویس‌هامحدودقابلیت‌های کامل systemd
پراکندگی زمان اجرادستیRandomizedDelaySec
قابلیت حملبالاتر در Unix/Linuxمخصوص سیستم‌های دارای systemd

برای یادگیری ساختار خود Cron نیز مقاله آموزش جامع Cron Job در لینوکس را بخوانید.

ساختار یک systemd Timer چگونه است؟

در حالت معمول دو فایل هم‌نام داریم؛ برای مثال backup-home.timer و backup-home.service. Timer زمان را کنترل می‌کند و Service اسکریپت واقعی را اجرا می‌کند. اگر در timer گزینه Unit= را مشخص نکنید، systemd معمولاً service هم‌نام را فعال می‌کند.

نمودار مسیر اجرای systemd Timer از زمان‌بندی تا Service و Task

آموزش ساخت systemd Timer برای بکاپ روزانه

فرض کنید اسکریپت بکاپ شما در مسیر /usr/local/sbin/backup-home.sh قرار دارد و می‌خواهید هر روز حدود ساعت 03:15 اجرا شود.

1. ساخت Service Unit

فایل زیر را بسازید:

sudo nano /etc/systemd/system/backup-home.service

محتوای نمونه:

[Unit]
Description=Daily home backup job

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/backup-home.sh
User=root

Type=oneshot برای کاری مناسب است که اجرا می‌شود، تمام می‌شود و لازم نیست به‌صورت daemon در پس‌زمینه باقی بماند. مسیر ExecStart را همیشه کامل بنویسید.

2. ساخت Timer Unit

sudo nano /etc/systemd/system/backup-home.timer
[Unit]
Description=Run home backup every day

[Timer]
OnCalendar=*-*-* 03:15:00
Persistent=true
RandomizedDelaySec=10m

[Install]
WantedBy=timers.target

OnCalendar زمان تقویمی را تعیین می‌کند. Persistent=true باعث می‌شود اگر اجرای تقویمی به‌دلیل خاموش بودن سیستم از دست رفت، پس از فعال شدن دوباره timer بررسی شود و اجرای جاافتاده انجام شود. RandomizedDelaySec=10m نیز زمان را تا ده دقیقه تصادفی عقب می‌اندازد؛ در چند سرور این کار جلوی شروع هم‌زمان بار سنگین را می‌گیرد.

3. بررسی عبارت زمانی قبل از فعال‌سازی

systemd-analyze calendar '*-*-* 03:15:00'

این دستور زمان اجرای بعدی را نشان می‌دهد و قبل از قرار دادن تنظیم در سرور Production کمک می‌کند خطای عبارت تقویمی را پیدا کنید.

4. Reload و فعال‌سازی Timer

sudo systemctl daemon-reload
sudo systemctl enable --now backup-home.timer

در این مرحله خود timer باید فعال باشد؛ لازم نیست service را enable کنید، چون timer آن را در زمان مقرر اجرا می‌کند.

چطور اجرای Timer را بررسی کنیم؟

برای مشاهده timerها و زمان اجرای بعدی:

systemctl list-timers --all

و برای وضعیت دقیق:

systemctl status backup-home.timer
systemctl status backup-home.service

لاگ اجرای job نیز به‌سادگی از journal قابل خواندن است:

journalctl -u backup-home.service --since today

قبل از منتظر ماندن برای زمان واقعی، service را یک بار دستی تست کنید:

sudo systemctl start backup-home.service
systemctl status backup-home.service

مهاجرت یک Cron Job به systemd Timer

فرض کنید در crontab این خط را دارید:

15 3 * * * /usr/local/sbin/backup-home.sh

معادل مفهومی آن در systemd همان Service و Timer بالاست: فرمان از crontab به ExecStart منتقل می‌شود و زمان 03:15 در OnCalendar قرار می‌گیرد. بعد از تست موفق timer، خط Cron قدیمی را حذف یا کامنت کنید تا job دوبار اجرا نشود.

زمان‌بندی نسبی با OnBootSec و OnUnitActiveSec

systemd فقط تقویم نیست. برای مثال، اگر می‌خواهید کاری 10 دقیقه بعد از بوت و سپس هر یک ساعت پس از آخرین فعال‌شدن اجرا شود:

[Timer]
OnBootSec=10m
OnUnitActiveSec=1h

این گزینه‌ها monotonic هستند و برای maintenanceهای دوره‌ای که به ساعت دیواری وابسته نیستند کاربرد دارند.

Persistent، AccuracySec و RandomizedDelaySec را درست بفهمیم

  • Persistent=true: برای timerهای مبتنی بر OnCalendar تاریخ آخرین trigger را نگه می‌دارد و اجرای جاافتاده را پس از بازگشت timer جبران می‌کند.
  • AccuracySec: پنجره دقت اجرای timer را کنترل می‌کند. این گزینه را با «تضمین اجرای دقیق در همان ثانیه» اشتباه نگیرید؛ systemd می‌تواند wake-upها را برای بهره‌وری بهتر هم‌زمان کند.
  • RandomizedDelaySec: اجرای timer را در یک بازه تصادفی پخش می‌کند؛ برای بکاپ، آپدیت یا maintenance روی تعداد زیادی VPS بسیار مفید است.

Best Practice برای Timerهای سرور

  • فرمان‌های طولانی را داخل ExecStart انباشته نکنید؛ اسکریپت قابل تست و نسخه‌بندی بسازید.
  • مسیر فایل‌ها و باینری‌ها را مطلق بنویسید؛ محیط systemd با shell تعاملی شما یکسان نیست.
  • در Service در صورت امکان از کاربر کم‌دسترسی استفاده کنید و فقط برای کارهای واقعاً سیستمی سراغ root بروید.
  • برای timerهای مهم، لاگ و exit code را مانیتور کنید؛ «فعال بودن timer» به‌تنهایی به معنی موفق بودن job نیست.
  • در Fleet چندسروری از RandomizedDelaySec استفاده کنید تا CPU، دیسک یا مقصد بکاپ هم‌زمان تحت فشار قرار نگیرد.
  • قبل از حذف Cron قدیمی، service را دستی و سپس timer را در یک بازه کوتاه تست کنید.

عیب‌یابی مشکلات رایج systemd Timer

مشکلبررسیراه‌حل
Timer فعال است ولی job اجرا نشدهsystemctl list-timers --allزمان NEXT، عبارت OnCalendar و timezone را بررسی کنید.
Timer trigger شده ولی نتیجه نداریمsystemctl status backup-home.serviceخطای Service را رفع کنید؛ Timer فقط trigger است.
فرمان در SSH کار می‌کند ولی در Service نهjournalctl -u backup-home.servicePATH، environment، permission و مسیر مطلق را بررسی کنید.
بعد از ویرایش فایل تغییر اعمال نشدهوضعیت unitsudo systemctl daemon-reload را اجرا کنید.
اجرای زمان خاموش بودن سرور از دست رفتهنوع timerبرای OnCalendar در صورت نیاز Persistent=true بگذارید.

Cron بهتر است یا systemd Timer؟

برای یک job بسیار ساده و محیطی که قابلیت حمل بین Unixها مهم است، Cron کم‌اصطکاک‌تر است. روی VPSهای مدرن مبتنی بر systemd، زمانی که مشاهده‌پذیری، مدیریت خطا، وابستگی، اجرای پس از بوت و کنترل دقیق‌تر مهم است، Timer انتخاب ساختاریافته‌تری محسوب می‌شود. هدف جایگزینی کورکورانه همه Cronها نیست؛ ابزار را بر اساس نیاز عملی انتخاب کنید.

سوالات متداول

آیا systemd Timer از Cron دقیق‌تر است؟

نه به‌صورت مطلق. systemd امکانات بیشتری برای کنترل زمان دارد، اما AccuracySec و سیاست‌های زمان‌بندی می‌توانند اجرای دقیق در همان ثانیه را تغییر دهند. برای اکثر کارهای مدیریتی سرور، این رفتار مطلوب است.

آیا Timer بعد از خاموش بودن سرور اجرای جاافتاده را انجام می‌دهد؟

برای timerهای تقویمی، اگر Persistent=true فعال باشد، systemd می‌تواند trigger جاافتاده را هنگام فعال شدن دوباره جبران کند.

چطور زمان اجرای بعدی Timer را ببینیم؟

از systemctl list-timers --all استفاده کنید. ستون NEXT زمان اجرای بعدی را نشان می‌دهد.

آیا می‌توان systemd Timer را برای کاربر عادی ساخت؟

بله، systemd از user units نیز پشتیبانی می‌کند و می‌توان با systemctl --user آن‌ها را مدیریت کرد؛ رفتار دقیق در زمان logout به تنظیمات session و linger وابسته است.

آیا Service را هم باید enable کنیم؟

در سناریوی معمول نه. Timer را enable می‌کنید و همان Timer در زمان مقرر Service را start می‌کند.

جمع‌بندی

systemd Timer با جداسازی زمان‌بندی از اجرای واقعی job، مدیریت وظایف دوره‌ای را در سرور لینوکس قابل‌مشاهده‌تر و قابل‌کنترل‌تر می‌کند. مهاجرت را از jobهای مهمی شروع کنید که به لاگ، جبران اجرای از‌دست‌رفته یا وابستگی‌های systemd نیاز دارند و بعد از تست، Cron قدیمی را حذف کنید.

اگر برای اجرای سرویس‌های لینوکسی، بکاپ خودکار یا jobهای دوره‌ای به محیط مستقل نیاز دارید، پلن‌های سرور مجازی وان سرور را می‌توانید بررسی کنید.

منابع

  • systemd.timer — مستندات رسمی systemd در freedesktop.org
  • Working with systemd Timers — مستندات SUSE Linux Enterprise Server
  • systemd/Timers — ArchWiki
Rate this post
اشتراک گذاری نوشته در:

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *