Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 任務排程精通:systemd Timer 取代 Cron 的現代化指南

編輯:Linux 教學

從 Cron 到 systemd Timer

傳統 cron 雖普及,但缺乏依賴管理、日誌整合、隨機延遲、持久化儲存。systemd Timer 提供:

  • 與 service 单元原生整合、依賴排序 (After/Requires)
  • 統一日誌 (journalctl -u timer-name)
  • RandomizedDelaySec、Persistent=true (開機補跑)
  • 單調時鐘 (Monotonic) 避免系統時間變更影響
  • systemd-analyze calendar 驗證時間表達式

Cron 基礎回顧 (兼容舊系統)

# 使用者 crontab
crontab -e
# 格式: 分 時 日 月 週 命令
0 2 * * * /backup.sh >> /var/log/backup.log 2>&1
*/15 * * * * /check_service.sh

# 系統 crontab (/etc/crontab) 含 USER 欄位
0 3 * * * root /scripts/daily_cleanup.sh

# 目錄式 (run-parts)
/etc/cron.d/        # 系統排程檔
/etc/cron.hourly/   # 每小時
/etc/cron.daily/    # 每天 (anacron 驅動)
/etc/cron.weekly/
/etc/cron.monthly/

systemd Timer 實戰

1. 基礎單元對:Service + Timer

/etc/systemd/system/backup.service

[Unit]
Description=Daily Backup Script
Documentation=man:backup(1)
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=backup
Group=backup
# 資源限制
MemoryMax=500M
CPUQuota=50%
# 環境
Environment=BACKUP_DEST=/mnt/backup
Environment=RETENTION_DAYS=30
# 日誌標籤
SyslogIdentifier=backup-script

[Install]
WantedBy=multi-user.target

/etc/systemd/system/backup.timer

[Unit]
Description=Run backup daily at 02:00 with random delay
Requires=backup.service

[Timer]
# Calendar 事件 (相對/絕對時間)
OnCalendar=*-*-* 02:00:00
# 或單調時間
# OnBootSec=15min
# OnUnitActiveSec=1d

# 關鍵現代化參數
RandomizedDelaySec=30m        # 0-30 分鐘隨機延遲,避免驚群
Persistent=true               # 開機時若錯過上次排程,立即執行
AccuracySec=1m                # 時間精度 (預設 1min)

[Install]
WantedBy=timers.target

2. 啟用與管理

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

# 查看狀態
systemctl list-timers --all
systemctl status backup.timer
journalctl -u backup.service -f

# 手動觸發
systemctl start backup.service

# 暫停/恢復
systemctl stop backup.timer
systemctl start backup.timer

3. Calendar 事件表達式速查

表達式含義
*-*-* 02:00:00每天 02:00
Mon *-*-* 03:00:00每週一 03:00
*-*-01 04:00:00每月 1 號 04:00
*-01,07-01 05:00:001 月與 7 月 1 號 05:00
Sat,Sun *-*-* 06:00:00週六日 06:00
*:0/15每 15 分鐘
daily每天 00:00 (內建別名)
weekly每週一 00:00
monthly每月 1 號 00:00
# 驗證表達式
systemd-analyze calendar "Mon *-*-* 03:00:00"
# 輸出下次觸發時間、間隔、經過時間

4. 進階模式

單一單元合併 (Type=oneshot + Timer 整合):簡單腳本可用 systemd-run 臨時排程:

# 一次性 10 分鐘後執行
systemd-run --on-active=10min /scripts/once.sh

# 每小時執行,隨機延遲 5 分鐘
systemd-run --on-calendar="*:0/60" --property=RandomizedDelaySec=5m /scripts/hourly.sh

多服務依賴鏈:

[Unit]
Description=Data Pipeline
After=extract.service transform.service
Requires=extract.service transform.service

[Service]
Type=oneshot
ExecStart=/scripts/load.sh

[Install]
WantedBy=multi-user.target

# Timer 只掛在最後一環
# load.timer → load.service → (Requires) transform.service → extract.service

Transient Timer (動態建立,不寫檔):

systemd-run --unit=myjob --on-calendar="*-*-* 03:00" --property=RandomizedDelaySec=1h /scripts/dynamic.sh

Anacron:非 24/7 系統的補救

筆記本/桌機非持續開機,anacron 讀取 /etc/anacrontab:

# 期間(天) 延遲(分) 識別名 命令
1   5   cron.daily   run-parts /etc/cron.daily
7   10  cron.weekly  run-parts /etc/cron.weekly
30  15  cron.monthly run-parts /etc/cron.monthly

# systemd 內建替代
# /etc/systemd/system/cron-daily.timer
[Timer]
OnCalendar=daily
RandomizedDelaySec=1h
Persistent=true

系統級定時任務最佳實踐

  1. 專用用戶/群組:useradd -r -s /sbin/nologin backup,最小權限
  2. 腳本健壯性:set -euo pipefail、鎖檔防重入 (flock)、超時控制 (timeout)、錯誤通知 (mail/curl webhook)
  3. 日誌輪替:StandardOutput=journal + journalctl --vacuum-time=30d,或導向檔案 + logrotate
  4. 監控告警:systemctl is-failed backup.service 整合 Prometheus node_exporter systemd_unit_failed 指標
  5. 版本控管:/etc/systemd/system/*.timer 納入 Git/Ansible/Salt
  6. 測試驗證:systemd-analyze verify backup.service backup.timer、systemd-dry-run

遷移清單:Cron → systemd Timer

Cron 特性systemd Timer 對應遷移步驟
使用者 crontab使用者級 systemd (systemd --user)loginctl enable-linger user; 放入 ~/.config/systemd/user/
MAILTO 郵件通知OnFailure=notify.service + sendmail/curl建立通知服務單元
@rebootWantedBy=multi-user.target + Type=oneshot服務設定 After=network-online.target
環境變數Environment= / EnvironmentFile=服務單元宣告
隨機延遲RandomizedDelaySec直接設定
錯過補跑Persistent=true直接設定
並發控制Type=oneshot + flock / systemd-run --property=LockPersonality=...服務單元加鎖

故障排查

# Timer 未觸發
systemctl list-timers --all | grep backup
systemctl status backup.timer
journalctl -u backup.timer -S -1h

# 服務失敗
journalctl -u backup.service -b
systemctl cat backup.service

# 時間表達式錯誤
systemd-analyze calendar "OnCalendar string"

# 權限問題
systemctl cat backup.service | grep User
sudo -u backup /usr/local/bin/backup.sh  # 手動測試

結論:新系統預設用 systemd Timer,舊系統 Cron 共存無害。Timer 提供企業級可觀測性、可靠性、可維護性,是基礎設施即代碼的原生選擇。

Copyright © Windows教程網 All Rights Reserved