Try   HackMD

使用 systemd timer 取代 crontab

  • 現代主流的 Linux 系統,預設使用 systemd 做系統管理
  • systemd timer 可取代 crontab,較易 debug 和操作,重要的工作推薦花時間改寫
  • 避免文章過於複雜,簡化功能描述
  • 本文假設用戶有 root 權限
  • 本文連結 : https://hackmd.io/@kmo/notes_systemd_timer

systemd timer 優點

  • 較容易 debug
  • 當上一時間步 foo.service 還處於執行狀態,下一時間步到了也不會重複執行 foo.service,可以避免重複執行造成 process 壘加,導致系統異常
    • 舉例來說:
      每 5 分鐘執行一次 foo.service,當 09 點 10 分到了,結果 09 點 05 分的 foo.service 還在執行中,foo.timer 判斷 foo.service 還是處於activating 狀態,就不會再啟動 foo.service
  • systemd timer 可精確到秒,以秒執行,而 crontab 較難以實現。比如 30 秒執行一次腳本,使用 systemd timer 可輕易實現
  • 可透過 foo.service 承接 Linux 的功能,比如限制使用的 CPU 和記憶體等

systemd timer 缺點

  • 相對於 crontab,使用 systemd timer 需要撰寫 2 個檔案
  • 學習曲線相對高。需要對 Linux 系統較高的熟悉度,才會較好理解,也比較不容易出錯

systemd 基本介紹

  • systemd 常見於系統以下 2 位置
# 用戶自定義檔案,也是接下來會用到路徑 /etc/systemd/system/* # 通常為系統安裝套件預設放置位置 (ex: deb, rpm...) /usr/lib/systemd/system/*
  • systemctl 基本指令
# 立即執行 or 停止指定的 service systemctl {start,stop} foo.service # 啟用 or 取消開機時會自動執行指定的 service systemctl {enable,disable} foo.service # 重啟指定的 service systemctl restart foo.service # 當有編輯 systemd,記得 reload systemctl daemon-reload
  • systemctl 操作以上指令,會記錄到作業系統的 syslog,如 CentOS 7 作業系統的 /var/log/messages
  • 當使用 systemctl 指令操作時,若沒有加結尾,預設你是指 .service 舉例如下,以下是相同指令
systemctl status foo systemctl status foo.service
  • 其他結尾有特定功能。例如本文介紹 *.timer*.timer 會去執行和自己同樣名稱的 *.service。如 foo.timer 時間到會去執行foo.service

systemd timer 範例

  • 為最簡單範例,只留下必要設定

情境

  • 每 5 分鐘執行一次腳本 /opt/foo.sh

撰寫 systemd 的檔案

  • 分別撰寫 2 個檔案,foo.servicefoo.timer 放底下指定路徑
  • service 功能 : 定義執行什麼工作 (what)
  • timer 功能 : 定義何時執行 (when)
  • /etc/systemd/system/foo.service
[Service] Type=oneshot ExecStart=/opt/foo.sh [Install] WantedBy=multi-user.target
  • /etc/systemd/system/foo.timer
[Timer] OnBootSec=5min OnUnitActiveSec=5min AccuracySec=1min [Install] WantedBy=timers.target
  • 當有編輯 systemd 記得 reload
systemctl daemon-reload

systemd 檔案參數說明

  • /etc/systemd/system/foo.service
Type=oneshot #oneshot 是指執行一次 ExecStart=/opt/foo.sh #這邊指定你要執行的腳本路徑,權限要可執行
  • /etc/systemd/system/foo.timer
OnBootSec=5min #開機後 5 分鐘執行 OnUnitActiveSec=5min #每 5 分鐘執行一次 AccuracySec=1min #精確到分鐘

測試及啟用 systemd

  • 主要腳本是透過 service 執行,先執行一次 foo.service,確認能成功執行
# start systemctl start foo.service # check status systemctl status foo.service
  • 執行 foo.timer,當設定的每 5 分鐘時間到了,foo.timer 會自動執行 foo.service
# start systemctl start foo.timer
  • 列出 timer 並查看 foo.timer 執行的狀態 (很重要的功能)
systemctl list-timers
  • 確認符合預期後,啟用讓他開機能自動執行
systemctl enable foo.timer

後記

  • 由於沒有詳盡到每個參數解釋,網路上也已經有很多不同詳細中文/英文資料說明 systemd,當有不懂推薦可以先 google 關鍵字查看看 :)

參考連結


Published on HackMD

https://hackmd.io/@kmo

作者

kmo

授權許可

CC BY-NC-SA 4.0