如何使用 systemd 內建的 time 來處理各種任務呢?
- systemd.timer 的優勢
在 archlinux 的官網 wiki 上面有提到,為啥要使用 systemd.timer 呢?
- 由於所有的 systemd 的服務產生的信息都會被紀錄 (log),因此比 crond 在 debug 上面要更清楚方便的多;
- 各項 timer 的工作可以跟 systemd 的服務相結合;
- 各項 timer 的工作可以跟 control group (cgroup,用來取代 /etc/secure/limit.conf 的功能) 結合,來限制該工作的資源利用
相對於 crond 最小的單位到分, systemd 是可以到秒甚至是毫秒的單位
- 任務需求
基本上,想要使用 systemd 的 timer 功能,你必須要有幾個要件:
- 系統的 timer.target 一定要啟動
- 要有個 sname.service 的服務存在 (sname 是你自己指定的名稱)
- 要有個 sname.timer 的時間啟動服務存在
- sname.timer 的設定值
你可以到 /etc/systemd/system 底下去建立這個 *.timer 檔,那這個文件的內容要項有哪些東西呢?基 本設定主要有底下這些: (man systemd.timer & man systemd.time)
[Timer] 部份:
設定參數 | 參數意義說明 |
---|---|
OnActiveSec | 當 timers.target 啟動多久之后才執行這只 unit |
OnBootSec | 當開機完成后多久之后才執行 |
OnStartupSec | 當 systemd 第一次啟動之后過多久才執行 |
OnUnitActiveSec | 這個 timer 配置文件所管理的那個 unit 服務在最后一次啟動后,隔多久后再執行一次的意思 |
OnUnitInactiveSec | 這個 timer 配置文件所管理的那個 unit 服務在最后一次停止后,隔多久再執行一次的意思。 |
OnCalendar | 使用實際時間 (非循環時間) 的方式來啟動服務的意思!至於時間的格式后續再來談。 |
Unit | 一般來說不太需要設定,因此如同上面剛剛提到的,基本上我們設定都是 sname.server + sname.timer,那如果你的 sname 並不相同時,那在 .timer 的文件中, 就得要指定是哪一個 service unit 啰! |
Persistent | 當使用 OnCalendar 的設定時,指定該功能要不要持續進行的意思。通常是設定為 yes ,比較能 夠滿足類似 anacron 的功能喔! |
- 使用於 OnCalendar 的時間
如果你想要從 crontab 轉成這個 timer 功能的話,那么對於時間設定的格式就得要了解了解~基本 上的格式如下所示:
語法:英文周名 YYYY-MM-DD HH:MM:SS
范例:Thu 2015-08-13 13:40:00
上面談的是基本的語法,你也可以直接使用間隔時間來處理!常用的間隔時間單位有:
- us 或 usec:微秒 (10-6 秒)
- ms 或 msec:毫秒 (10-3 秒)
- s, sec, second, seconds
- m, min, minute, minutes
- h, hr, hour, hours
- d, day, days
- w, week, weeks
- month, months
- y, year, years
常見的使用范例有:
隔3小時: 3h 或 3hr 或 3hours
隔 300 分鍾過 10 秒: 10s 300m
隔 5 天又 100 分鍾: 100m 5day
# 通常英文的寫法,小單位寫前面,大單位寫后面~所以先秒、再分、再小時、再天數等~
此外,你也可以使用英文常用的口語化日期代表,例如 today, tomorrow 等!假設今天是 2015-08-13 13:50:00 的話,那么:
英文口語 | 實際的時間格式代表 |
---|---|
now | Thu 2015-08-13 13:50:00 |
today | Thu 2015-08-13 00:00:00 |
tomorrow | Thu 2015-08-14 00:00:00 |
hourly | --* *:00:00 |
daily | --* 00:00:00 |
weekly | Mon --* 00:00:00 |
monthly | --01 00:00:00 |
+3h10m | Thu 2015-08-13 17:00:00 |
2015-08-16 | Sun 2015-08-16 00:00:00 |
- 一個循環時間運作的案例
現在假設這樣:
- 開機后 2 小時開始執行一次這個 backup.service
- 自從第一次執行后,未來我每兩天要執行一次 backup.service
可以這樣做
[root@study ~]# vim /etc/systemd/system/backup.timer
[Unit]
Description=backup my server timer
[Timer]
OnBootSec=2hrs
OnUnitActiveSec=2days
[Install]
WantedBy=multi-user.target
# 只要這樣設定就夠了!儲存離開吧!
[root@study ~]# systemctl daemon-reload
[root@study ~]# systemctl enable backup.timer
[root@study ~]# systemctl restart backup.timer
[root@study ~]# systemctl list-unit-files | grep backup
backup.service disabled # 這個不需要啟動!只要 enable backup.timer 即可!
backup.timer enabled
[root@study ~]# systemctl show timers.target
ConditionTimestamp=Thu 2015-08-13 14:31:11 CST # timer 這個 unit 啟動的時間!
[root@study ~]# systemctl show backup.service
ExecMainExitTimestamp=Thu 2015-08-13 14:50:19 CST # backup.service 上次執行的時間
[root@study ~]# systemctl show backup.timer
NextElapseUSecMonotonic=2d 19min 11.540653s # 下一次執行距離 timers.target 的時間
我上次執行 backup.service 的時間是在 2015-08-13 14:50 ,由於設定兩個小時執行一 次,因此下次應該是 2015-08-15 14:50 執行才對! 由於 timer 是由 timers.target 這個 unit 所管理 的,而這個 timers.target 的啟動時間是在 2015-08-13 14:31 , 要注意,最終 backup.timer 所紀錄的
下次運行時間,其實是與 timers.target 所紀錄的時間差!因此是『 2015-08-15 14:50 - 2015-08-13 14:31 』才對! 所以時間差就是 2d 19min 啰!
- 一個固定日期運作的案例
那如果我希望不管上面如何運作了,我都希望星期天凌晨 2 點運 作這個備份程序一遍呢?請注意,因為已經存在 backup.timer 了!所以,這里我用 backup2.timer 來做區隔!
[root@study ~]# vim /etc/systemd/system/backup2.timer
[Unit]
Description=backup my server timer2
[Timer]
OnCalendar=Sun *-*-* 02:00:00
Persistent=true
Unit=backup.service
[Install]
WantedBy=multi-user.target
[root@study ~]# systemctl daemon-reload
[root@study ~]# systemctl enable backup2.timer
[root@study ~]# systemctl start backup2.timer
[root@study ~]# systemctl show backup2.timer
NextElapseUSecRealtime=45y 7month 1w 6d 10h 30min
與循環時間運作差異比較大的地方,在於這個 OnCalendar 的方法對照的時間並不是 times.target 的 啟動時間,而是 Unix 標准時間! 亦即是 1970-01-01 00:00:00 去比較的!