溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何使用 systemd 定時器代替 cron 作業(yè)

發(fā)布時間:2021-07-07 17:39:38 來源:億速云 閱讀:259 作者:chen 欄目:系統(tǒng)運維

這篇文章主要講解了“如何使用 systemd 定時器代替 cron 作業(yè)”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“如何使用 systemd 定時器代替 cron 作業(yè)”吧!


定時器提供了比 cron 作業(yè)更為細(xì)粒度的事件控制。

我正在致力于將我的 cron 作業(yè)遷移到 systemd 定時器上。我已經(jīng)使用定時器多年了,但通常來說,我的學(xué)識只足以支撐我當(dāng)前的工作。但在我研究 systemd 系列 的過程中,我發(fā)現(xiàn) systemd 定時器有一些非常有意思的能力。

與 cron 作業(yè)類似,systemd 定時器可以在特定的時間間隔觸發(fā)事件(shell  腳本和程序),例如每天一次或在一個月中的特定某一天(或許只有在周一生效),或在從上午 8 點到下午 6 點的工作時間內(nèi)每隔 15  分鐘一次。定時器也可以做到 cron  作業(yè)無法做到的一些事情。舉個例子,定時器可以在特定事件發(fā)生后的一段時間后觸發(fā)一段腳本或者程序去執(zhí)行,例如開機、啟動、上個任務(wù)完成,甚至于定時器調(diào)用的上個服務(wù)單元的完成的時刻。

操作系統(tǒng)維護的計時器

當(dāng)在一個新系統(tǒng)上安裝 Fedora 或者是任意一個基于 systemd 的發(fā)行版時,作為系統(tǒng)維護過程的一部分,它會在 Linux  宿主機的后臺中創(chuàng)建多個定時器。這些定時器會觸發(fā)事件來執(zhí)行必要的日常維護任務(wù),比如更新系統(tǒng)數(shù)據(jù)庫、清理臨時目錄、輪換日志文件,以及更多其他事件。

作為示例,我會查看一些我的主要工作站上的定時器,通過執(zhí)行 systemctl status *timer 命令來展示主機上的所有定時器。星號的作用與文件通配相同,所以這個命令會列出所有的 systemd 定時器單元。

[root@testvm1 ~]# systemctl status *timer● mlocate-updatedb.timer - Updates mlocate database every day     Loaded: loaded (/usr/lib/systemd/system/mlocate-updatedb.timer; enabled; vendor preset: enabled)     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago    Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left   Triggers: ● mlocate-updatedb.service Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Updates mlocate database every day. ● logrotate.timer - Daily rotation of log files     Loaded: loaded (/usr/lib/systemd/system/logrotate.timer; enabled; vendor preset: enabled)     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago    Trigger: Fri 2020-06-05 00:00:00 EDT; 15h left   Triggers: ● logrotate.service       Docs: man:logrotate(8)             man:logrotate.conf(5) Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily rotation of log files. ● sysstat-summary.timer - Generate summary of yesterday's process accounting     Loaded: loaded (/usr/lib/systemd/system/sysstat-summary.timer; enabled; vendor preset: enabled)     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago    Trigger: Fri 2020-06-05 00:07:00 EDT; 15h left   Triggers: ● sysstat-summary.service Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Generate summary of yesterday's process accounting. ● fstrim.timer - Discard unused blocks once a week     Loaded: loaded (/usr/lib/systemd/system/fstrim.timer; enabled; vendor preset: enabled)     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago    Trigger: Mon 2020-06-08 00:00:00 EDT; 3 days left   Triggers: ● fstrim.service       Docs: man:fstrim Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Discard unused blocks once a week. ● sysstat-collect.timer - Run system activity accounting tool every 10 minutes     Loaded: loaded (/usr/lib/systemd/system/sysstat-collect.timer; enabled; vendor preset: enabled)     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago    Trigger: Thu 2020-06-04 08:50:00 EDT; 41s left   Triggers: ● sysstat-collect.service Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Run system activity accounting tool every 10 minutes. ● dnf-makecache.timer - dnf makecache --timer     Loaded: loaded (/usr/lib/systemd/system/dnf-makecache.timer; enabled; vendor preset: enabled)     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago    Trigger: Thu 2020-06-04 08:51:00 EDT; 1min 41s left   Triggers: ● dnf-makecache.service Jun 02 08:02:33 testvm1.both.org systemd[1]: Started dnf makecache –timer. ● systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories     Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.timer; static; vendor preset: disabled)     Active: active (waiting) since Tue 2020-06-02 08:02:33 EDT; 2 days ago    Trigger: Fri 2020-06-05 08:19:00 EDT; 23h left   Triggers: ● systemd-tmpfiles-clean.service       Docs: man:tmpfiles.d(5)             man:systemd-tmpfiles(8) Jun 02 08:02:33 testvm1.both.org systemd[1]: Started Daily Cleanup of Temporary Directories.

每個定時器至少有六行相關(guān)信息:

  • 定時器的第一行有定時器名字和定時器目的的簡短介紹

  • 第二行展示了定時器的狀態(tài),是否已加載,定時器單元文件的完整路徑以及預(yù)設(shè)信息。

  • 第三行指明了其活動狀態(tài),包括該定時器激活的日期和時間。

  • 第四行包括了該定時器下次被觸發(fā)的日期和時間和距離觸發(fā)的大概時間。

  • 第五行展示了被定時器觸發(fā)的事件或服務(wù)名稱。

  • 部分(不是全部)systemd 單元文件有相關(guān)文檔的指引。我虛擬機上輸出中有三個定時器有文檔指引。這是一個很好(但非必要)的信息。

  • 最后一行是計時器最近觸發(fā)的服務(wù)實例的日志條目。

你也許有一些不一樣的定時器,取決于你的主機。

創(chuàng)建一個定時器

盡管我們可以解構(gòu)一個或多個現(xiàn)有的計時器來了解其工作原理,但讓我們創(chuàng)建我們自己的 服務(wù)單元 和一個定時器去觸發(fā)它。為了保持簡單,我們將使用一個相當(dāng)簡單的例子。當(dāng)我們完成這個實驗之后,就能更容易理解其他定時器的工作原理以及發(fā)現(xiàn)它們正在做什么。

首先,創(chuàng)建一個運行基礎(chǔ)東西的簡單的服務(wù),例如 free 命令。舉個例子,你可能想定時監(jiān)控空余內(nèi)存。在 /etc/systemd/system 目錄下創(chuàng)建如下的 myMonitor.server 單元文件。它不需要是可執(zhí)行文件:

# This service unit is for testing timer units# By David Both# Licensed under GPL V2# [Unit]Description=Logs system statistics to the systemd journalWants=myMonitor.timer [Service]Type=oneshotExecStart=/usr/bin/free [Install]WantedBy=multi-user.target

這大概是你能創(chuàng)建的最簡單的服務(wù)單元了?,F(xiàn)在我們查看一下服務(wù)狀態(tài)同時測試一下服務(wù)單元確保它和我們預(yù)期一樣可用。

[root@testvm1 system]# systemctl status myMonitor.service● myMonitor.service - Logs system statistics to the systemd journal     Loaded: loaded (/etc/systemd/system/myMonitor.service; disabled; vendor preset: disabled)     Active: inactive (dead)[root@testvm1 system]# systemctl start myMonitor.service[root@testvm1 system]#

輸出在哪里呢?默認(rèn)情況下,systemd 服務(wù)單元執(zhí)行程序的標(biāo)準(zhǔn)輸出(STDOUT)會被發(fā)送到系統(tǒng)日志中,它保留了記錄供現(xiàn)在或者之后(直到某個時間點)查看。(在本系列的后續(xù)文章中,我將介紹系統(tǒng)日志的記錄和保留策略)。專門查看你的服務(wù)單元的日志,而且只針對今天。-S 選項,即 --since 的縮寫,允許你指定 journalctl 工具搜索條目的時間段。這并不代表你不關(guān)心過往結(jié)果 —— 在這個案例中,不會有過往記錄 —— 如果你的機器以及運行了很長時間且堆積了大量的日志,它可以縮短搜索時間。

[root@testvm1 system]# journalctl -S today -u myMonitor.service-- Logs begin at Mon 2020-06-08 07:47:20 EDT, end at Thu 2020-06-11 09:40:47 EDT. --Jun 11 09:12:09 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...Jun 11 09:12:09 testvm1.both.org free[377966]:               total        used        free      shared  buff/cache   availableJun 11 09:12:09 testvm1.both.org free[377966]: Mem:       12635740      522868    11032860        8016     1080012    11821508Jun 11 09:12:09 testvm1.both.org free[377966]: Swap:       8388604           0     8388604Jun 11 09:12:09 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.[root@testvm1 system]#

由服務(wù)觸發(fā)的任務(wù)可以是單個程序、一組程序或者是一個腳本語言寫的腳本。通過在 myMonitor.service 單元文件里的 [Service] 塊末尾中添加如下行可以為服務(wù)添加另一個任務(wù):

ExecStart=/usr/bin/lsblk

再次啟動服務(wù),查看日志檢查結(jié)果,結(jié)果應(yīng)該看上去像這樣。你應(yīng)該在日志中看到兩條命令的結(jié)果輸出:

Jun 11 15:42:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...Jun 11 15:42:18 testvm1.both.org free[379961]:               total        used        free      shared  buff/cache   availableJun 11 15:42:18 testvm1.both.org free[379961]: Mem:       12635740      531788    11019540        8024     1084412    11812272Jun 11 15:42:18 testvm1.both.org free[379961]: Swap:       8388604           0     8388604Jun 11 15:42:18 testvm1.both.org lsblk[379962]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTJun 11 15:42:18 testvm1.both.org lsblk[379962]: sda             8:0    0  120G  0 diskJun 11 15:42:18 testvm1.both.org lsblk[379962]: ├─sda1          8:1    0    4G  0 part /bootJun 11 15:42:18 testvm1.both.org lsblk[379962]: └─sda2          8:2    0  116G  0 partJun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-root 253:0    0    5G  0 lvm  /Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]Jun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usrJun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmpJun 11 15:42:18 testvm1.both.org lsblk[379962]:   ├─VG01-var  253:4    0   20G  0 lvm  /varJun 11 15:42:18 testvm1.both.org lsblk[379962]:   └─VG01-home 253:5    0   10G  0 lvm  /homeJun 11 15:42:18 testvm1.both.org lsblk[379962]: sr0            11:0    1 1024M  0 romJun 11 15:42:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.Jun 11 15:42:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.

現(xiàn)在你知道了你的服務(wù)可以按預(yù)期工作了,在 /etc/systemd/system 目錄下創(chuàng)建 myMonitor.timer 定時器單元文件,添加如下代碼:

# This timer unit is for testing# By David Both# Licensed under GPL V2# [Unit]Description=Logs some system statistics to the systemd journalRequires=myMonitor.service [Timer]Unit=myMonitor.serviceOnCalendar=*-*-* *:*:00 [Install]WantedBy=timers.target

在 myMonitor.timer 文件中的 OnCalendar 時間格式,*-*-* *:*:00,應(yīng)該會每分鐘觸發(fā)一次定時器去執(zhí)行 myMonitor.service 單元。我會在文章的后面進一步探索 OnCalendar 設(shè)置。

到目前為止,在服務(wù)被計時器觸發(fā)運行時觀察與之有關(guān)的日志記錄。你也可以跟蹤計時器,跟蹤服務(wù)可以讓你接近實時的看到結(jié)果。執(zhí)行 journalctl 時帶上 -f 選項:

[root@testvm1 system]# journalctl -S today -f -u myMonitor.service-- Logs begin at Mon 2020-06-08 07:47:20 EDT. --

執(zhí)行但是不啟用該定時器,看看它運行一段時間后發(fā)生了什么:

[root@testvm1 ~]# systemctl start myMonitor.service[root@testvm1 ~]#

一條結(jié)果立即就顯示出來了,下一條大概在一分鐘后出來。觀察幾分鐘日志,看看你有沒有跟我發(fā)現(xiàn)同樣的事情:

[root@testvm1 system]# journalctl -S today -f -u myMonitor.service-- Logs begin at Mon 2020-06-08 07:47:20 EDT. --Jun 13 08:39:18 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...Jun 13 08:39:18 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.Jun 13 08:39:19 testvm1.both.org free[630566]:               total        used        free      shared  buff/cache   availableJun 13 08:39:19 testvm1.both.org free[630566]: Mem:       12635740      556604    10965516        8036     1113620    11785628Jun 13 08:39:19 testvm1.both.org free[630566]: Swap:       8388604           0     8388604Jun 13 08:39:18 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.Jun 13 08:39:19 testvm1.both.org lsblk[630567]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTJun 13 08:39:19 testvm1.both.org lsblk[630567]: sda             8:0    0  120G  0 diskJun 13 08:39:19 testvm1.both.org lsblk[630567]: ├─sda1          8:1    0    4G  0 part /bootJun 13 08:39:19 testvm1.both.org lsblk[630567]: └─sda2          8:2    0  116G  0 partJun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-root 253:0    0    5G  0 lvm  /Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]Jun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usrJun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmpJun 13 08:39:19 testvm1.both.org lsblk[630567]:   ├─VG01-var  253:4    0   20G  0 lvm  /varJun 13 08:39:19 testvm1.both.org lsblk[630567]:   └─VG01-home 253:5    0   10G  0 lvm  /homeJun 13 08:39:19 testvm1.both.org lsblk[630567]: sr0            11:0    1 1024M  0 romJun 13 08:40:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...Jun 13 08:40:46 testvm1.both.org free[630572]:               total        used        free      shared  buff/cache   availableJun 13 08:40:46 testvm1.both.org free[630572]: Mem:       12635740      555228    10966836        8036     1113676    11786996Jun 13 08:40:46 testvm1.both.org free[630572]: Swap:       8388604           0     8388604Jun 13 08:40:46 testvm1.both.org lsblk[630574]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTJun 13 08:40:46 testvm1.both.org lsblk[630574]: sda             8:0    0  120G  0 diskJun 13 08:40:46 testvm1.both.org lsblk[630574]: ├─sda1          8:1    0    4G  0 part /bootJun 13 08:40:46 testvm1.both.org lsblk[630574]: └─sda2          8:2    0  116G  0 partJun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-root 253:0    0    5G  0 lvm  /Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]Jun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usrJun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmpJun 13 08:40:46 testvm1.both.org lsblk[630574]:   ├─VG01-var  253:4    0   20G  0 lvm  /varJun 13 08:40:46 testvm1.both.org lsblk[630574]:   └─VG01-home 253:5    0   10G  0 lvm  /homeJun 13 08:40:46 testvm1.both.org lsblk[630574]: sr0            11:0    1 1024M  0 romJun 13 08:40:46 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.Jun 13 08:40:46 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.Jun 13 08:41:46 testvm1.both.org systemd[1]: Starting Logs system statistics to the systemd journal...Jun 13 08:41:46 testvm1.both.org free[630580]:               total        used        free      shared  buff/cache   availableJun 13 08:41:46 testvm1.both.org free[630580]: Mem:       12635740      553488    10968564        8036     1113688    11788744Jun 13 08:41:46 testvm1.both.org free[630580]: Swap:       8388604           0     8388604Jun 13 08:41:47 testvm1.both.org lsblk[630581]: NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTJun 13 08:41:47 testvm1.both.org lsblk[630581]: sda             8:0    0  120G  0 diskJun 13 08:41:47 testvm1.both.org lsblk[630581]: ├─sda1          8:1    0    4G  0 part /bootJun 13 08:41:47 testvm1.both.org lsblk[630581]: └─sda2          8:2    0  116G  0 partJun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-root 253:0    0    5G  0 lvm  /Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-swap 253:1    0    8G  0 lvm  [SWAP]Jun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-usr  253:2    0   30G  0 lvm  /usrJun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-tmp  253:3    0   10G  0 lvm  /tmpJun 13 08:41:47 testvm1.both.org lsblk[630581]:   ├─VG01-var  253:4    0   20G  0 lvm  /varJun 13 08:41:47 testvm1.both.org lsblk[630581]:   └─VG01-home 253:5    0   10G  0 lvm  /homeJun 13 08:41:47 testvm1.both.org lsblk[630581]: sr0            11:0    1 1024M  0 romJun 13 08:41:47 testvm1.both.org systemd[1]: myMonitor.service: Succeeded.Jun 13 08:41:47 testvm1.both.org systemd[1]: Finished Logs system statistics to the systemd journal.

別忘了檢查下計時器和服務(wù)的狀態(tài)。

你在日志里大概至少注意到兩件事。第一,你不需要特地做什么來讓 myMonitor.service 單元中 ExecStart 觸發(fā)器產(chǎn)生的 STDOUT 存儲到日志里。這都是用 systemd 來運行服務(wù)的一部分功能。然而,它確實意味著你需要小心對待服務(wù)單元里面執(zhí)行的腳本和它們能產(chǎn)生多少 STDOUT

第二,定時器并不是精確在每分鐘的 :00 秒執(zhí)行的,甚至每次執(zhí)行的時間間隔都不是剛好一分鐘。這是特意的設(shè)計,但是有必要的話可以改變這種行為(如果只是它挑戰(zhàn)了你的系統(tǒng)管理員的敏感神經(jīng))。

這樣設(shè)計的初衷是為了防止多個服務(wù)在完全相同的時刻被觸發(fā)。舉個例子,你可以用例如 Weekly,Daily 等時間格式。這些快捷寫法都被定義為在某一天的 00:00:00 執(zhí)行。當(dāng)多個定時器都這樣定義的話,有很大可能它們會同時執(zhí)行。

systemd 定時器被故意設(shè)計成在規(guī)定時間附近隨機波動的時間點觸發(fā),以避免同一時間觸發(fā)。它們在一個時間窗口內(nèi)半隨機觸發(fā),時間窗口開始于預(yù)設(shè)的觸發(fā)時間,結(jié)束于預(yù)設(shè)時間后一分鐘。根據(jù) systemd.timer 的手冊頁,這個觸發(fā)時間相對于其他已經(jīng)定義的定時器單元保持在穩(wěn)定的位置。你可以在日志條目中看到,定時器在啟動后立即觸發(fā),然后在每分鐘后的 46 或 47 秒觸發(fā)。

大部分情況下,這種概率抖動的定時器是沒事的。當(dāng)調(diào)度類似執(zhí)行備份的任務(wù),只需要它們在下班時間運行,這樣是沒問題的。系統(tǒng)管理員可以選擇確定的開始時間來確保不和其他任務(wù)沖突,例如  01:05:00 這樣典型的 cron 作業(yè)時間,但是有很大范圍的時間值可以滿足這一點。在開始時間上的一個分鐘級別的隨機往往是無關(guān)緊要的。

然而,對某些任務(wù)來說,精確的觸發(fā)時間是個硬性要求。對于這類任務(wù),你可以向單元文件的 Timer 塊中添加如下聲明來指定更高的觸發(fā)時間跨度精確度(精確到微秒以內(nèi)):

AccuracySec=1us

時間跨度可用于指定所需的精度,以及定義重復(fù)事件或一次性事件的時間跨度。它能識別以下單位:

  • usec,us,µs

  • msec,ms

  • secondssecond,secs

  • minutes,minute,minm

  • hours,hour,hrh

  • days,day,d

  • weeks,weekw

  • months,month,M(定義為 30.44 天)

  • yearsyear,y(定義為 365.25 天)

所有 /usr/lib/systemd/system 中的定時器都指定了一個更寬松的時間精度,因為精準(zhǔn)時間沒那么重要??纯催@些系統(tǒng)創(chuàng)建的定時器的時間格式:

[root@testvm1 system]# grep Accur /usr/lib/systemd/system/*timer/usr/lib/systemd/system/fstrim.timer:AccuracySec=1h/usr/lib/systemd/system/logrotate.timer:AccuracySec=1h/usr/lib/systemd/system/logwatch.timer:AccuracySec=12h/usr/lib/systemd/system/mlocate-updatedb.timer:AccuracySec=24h/usr/lib/systemd/system/raid-check.timer:AccuracySec=24h/usr/lib/systemd/system/unbound-anchor.timer:AccuracySec=24h[root@testvm1 system]#

看下 /usr/lib/systemd/system 目錄下部分定時器單元文件的完整內(nèi)容,看看它們是如何構(gòu)建的。

在本實驗中不必讓這個定時器在啟動時激活,但下面這個命令可以設(shè)置開機自啟:

[root@testvm1 system]# systemctl enable myMonitor.timer

你創(chuàng)建的單元文件不需要是可執(zhí)行的。你同樣不需要啟用服務(wù),因為它是被定時器觸發(fā)的。如果你需要的話,你仍然可以在命令行里手動觸發(fā)該服務(wù)單元。嘗試一下,然后觀察日志。

關(guān)于定時器精度、事件時間規(guī)格和觸發(fā)事件的詳細(xì)信息,請參見 systemd.timer 和 systemd.time 的手冊頁。

定時器類型

systemd 定時器還有一些在 cron 中找不到的功能,cron 只在確定的、重復(fù)的、具體的日期和時間觸發(fā)。systemd  定時器可以被配置成根據(jù)其他 systemd  單元狀態(tài)發(fā)生改變時觸發(fā)。舉個例子,定時器可以配置成在系統(tǒng)開機、啟動后,或是某個確定的服務(wù)單元激活之后的一段時間被觸發(fā)。這些被稱為單調(diào)計時器。“單調(diào)”指的是一個持續(xù)增長的計數(shù)器或序列。這些定時器不是持久的,因為它們在每次啟動后都會重置。

表格 1 列出了一些單調(diào)定時器以及每個定時器的簡短定義,同時有 OnCalendar 定時器,這些不是單調(diào)的,它們被用于指定未來有可能重復(fù)的某個確定時間。這個信息來自于 systemd.timer 的手冊頁,有一些不重要的修改。

< 如顯示不全,請左右滑動 >
定時器單調(diào)性定義
OnActiveSec=X定義了一個與定時器被激活的那一刻相關(guān)的定時器。
OnBootSec=X定義了一個與機器啟動時間相關(guān)的計時器。
OnStartupSec=X定義了一個與服務(wù)管理器首次啟動相關(guān)的計時器。對于系統(tǒng)定時器來說,這個定時器與 OnBootSec= 類似,因為系統(tǒng)服務(wù)管理器在機器啟動后很短的時間后就會啟動。當(dāng)以在每個用戶服務(wù)管理器中運行的單元進行配置時,它尤其有用,因為用戶的服務(wù)管理器通常在首次登錄后啟動,而不是機器啟動后。
OnUnitActiveSec=X定義了一個與將要激活的定時器上次激活時間相關(guān)的定時器。
OnUnitInactiveSec=X定義了一個與將要激活的定時器上次停用時間相關(guān)的定時器。
OnCalendar= 定義了一個有日期事件表達(dá)式語法的實時(即時鐘)定時器。查看 systemd.time(7) 的手冊頁獲取更多與日歷事件表達(dá)式相關(guān)的語法信息。除此以外,它的語義和 OnActiveSec= 類似。

Table 1: systemd 定時器定義

單調(diào)計時器可使用同樣的簡寫名作為它們的時間跨度,即我們之前提到的 AccuracySec 表達(dá)式,但是 systemd 將這些名字統(tǒng)一轉(zhuǎn)換成了秒。舉個例子,比如你想規(guī)定某個定時器在系統(tǒng)啟動后五天觸發(fā)一次事件;它可能看起來像 OnBootSec=5d。如果機器啟動于 2020-06-15 09:45:27,這個定時器會在 2020-06-20 09:45:27 或在這之后的一分鐘內(nèi)觸發(fā)。

日歷事件格式

日歷事件格式是定時器在所需的重復(fù)時間觸發(fā)的關(guān)鍵。我們開始看下一些 OnCalendar 設(shè)置一起使用的格式。

與 crontab 中的格式相比,systemd 及其計時器使用的時間和日歷格式風(fēng)格不同。它比 crontab 更為靈活,而且可以使用類似 at 命令的方式允許模糊的日期和時間。它還應(yīng)該足夠熟悉使其易于理解。

systemd 定時器使用 OnCalendar= 的基礎(chǔ)格式是 DOW YYYY-MM-DD HH:MM:SS。DOW(星期幾)是選填的,其他字段可以用一個星號(*)來匹配此位置的任意值。所有的日歷時間格式會被轉(zhuǎn)換成標(biāo)準(zhǔn)格式。如果時間沒有指定,它會被設(shè)置為 00:00:00。如果日期沒有指定但是時間指定了,那么下次匹配的時間可能是今天或者明天,取決于當(dāng)前的時間。月份和星期可以使用名稱或數(shù)字。每個單元都可以使用逗號分隔的列表。單元范圍可以在開始值和結(jié)束值之間用 .. 指定。

指定日期有一些有趣的選項,波浪號(~)可以指定月份的最后一天或者最后一天之前的某幾天。/ 可以用來指定星期幾作為修飾符。

這里有幾個在 OnCalendar 表達(dá)式中使用的典型時間格式例子。

日期事件格式描述
DOW YYYY-MM-DD HH:MM:SS 
*-*-* 00:15:30每年每月每天的 0 點 15 分 30 秒
Weekly每個周一的 00:00:00
Mon *-*-* 00:00:00同上
Mon同上
Wed 2020-*-*2020 年每個周三的 00:00:00
Mon..Fri 2021-*-*2021 年的每個工作日(周一到周五)的 00:00:00
2022-6,7,8-1,15 01:15:002022 年 6、7、8 月的 1 到 15 號的 01:15:00
Mon *-05~03每年五月份的下個周一同時也是月末的倒數(shù)第三天
Mon..Fri *-08~04任何年份 8 月末的倒數(shù)第四天,同時也須是工作日
*-05~03/2五月末的倒數(shù)第三天,然后 2 天后再來一次。每年重復(fù)一次。注意這個表達(dá)式使用了波浪號(~)。
*-05-03/2五月的第三天,然后每兩天重復(fù)一次直到 5 月底。注意這個表達(dá)式使用了破折號(-)。

Table 2: OnCalendar 事件時間格式例子

測試日歷格式

systemd 提供了一個絕佳的工具用于檢測和測試定時器中日歷時間事件的格式。systemd-analyze calendar 工具解析一個時間事件格式,提供標(biāo)準(zhǔn)格式和其他有趣的信息,例如下次“經(jīng)過”(即匹配)的日期和時間,以及距離下次觸發(fā)之前大概時間。

首先,看看未來沒有時間的日(注意 Next elapse 和 UTC 的時間會根據(jù)你當(dāng)?shù)貢r區(qū)改變):

[student@studentvm1 ~]$ systemd-analyze calendar 2030-06-17  Original form: 2030-06-17                Normalized form: 2030-06-17 00:00:00            Next elapse: Mon 2030-06-17 00:00:00 EDT       (in UTC): Mon 2030-06-17 04:00:00 UTC       From now: 10 years 0 months left    [root@testvm1 system]#

現(xiàn)在添加一個時間,在這個例子中,日期和時間是當(dāng)作無關(guān)的部分分開解析的:

[root@testvm1 system]# systemd-analyze calendar 2030-06-17 15:21:16  Original form: 2030-06-17                Normalized form: 2030-06-17 00:00:00            Next elapse: Mon 2030-06-17 00:00:00 EDT       (in UTC): Mon 2030-06-17 04:00:00 UTC       From now: 10 years 0 months left       Original form: 15:21:16                  Normalized form: *-*-* 15:21:16                Next elapse: Mon 2020-06-15 15:21:16 EDT       (in UTC): Mon 2020-06-15 19:21:16 UTC       From now: 3h 55min left              [root@testvm1 system]#

為了把日期和時間當(dāng)作一個單元來分析,可以把它們包在引號里。你在定時器單元里 OnCalendar= 時間格式中使用的時候記得把引號去掉,否則會報錯:

[root@testvm1 system]# systemd-analyze calendar "2030-06-17 15:21:16"Normalized form: 2030-06-17 15:21:16            Next elapse: Mon 2030-06-17 15:21:16 EDT       (in UTC): Mon 2030-06-17 19:21:16 UTC       From now: 10 years 0 months left    [root@testvm1 system]#

現(xiàn)在我們測試下 Table2 里的例子。我尤其喜歡最后一個:

[root@testvm1 system]# systemd-analyze calendar "2022-6,7,8-1,15 01:15:00"  Original form: 2022-6,7,8-1,15 01:15:00Normalized form: 2022-06,07,08-01,15 01:15:00    Next elapse: Wed 2022-06-01 01:15:00 EDT       (in UTC): Wed 2022-06-01 05:15:00 UTC       From now: 1 years 11 months left[root@testvm1 system]#

讓我們看一個例子,這個例子里我們列出了時間表達(dá)式的五個經(jīng)過時間。

[root@testvm1 ~]# systemd-analyze calendar --iterations=5 "Mon *-05~3"  Original form: Mon *-05~3                Normalized form: Mon *-05~03 00:00:00          Next elapse: Mon 2023-05-29 00:00:00 EDT       (in UTC): Mon 2023-05-29 04:00:00 UTC       From now: 2 years 11 months left           Iter. #2: Mon 2028-05-29 00:00:00 EDT       (in UTC): Mon 2028-05-29 04:00:00 UTC       From now: 7 years 11 months left           Iter. #3: Mon 2034-05-29 00:00:00 EDT       (in UTC): Mon 2034-05-29 04:00:00 UTC       From now: 13 years 11 months left           Iter. #4: Mon 2045-05-29 00:00:00 EDT       (in UTC): Mon 2045-05-29 04:00:00 UTC       From now: 24 years 11 months left           Iter. #5: Mon 2051-05-29 00:00:00 EDT       (in UTC): Mon 2051-05-29 04:00:00 UTC       From now: 30 years 11 months left    [root@testvm1 ~]#

這些應(yīng)該為你提供了足夠的信息去開始測試你的 OnCalendar 時間格式。systemd-analyze 工具可用于其他有趣的分析,我會在這個系列的下一篇文章來探索這些。

總結(jié)

systemd 定時器可以用于執(zhí)行和 cron 工具相同的任務(wù),但是通過按照日歷和單調(diào)時間格式去觸發(fā)事件的方法提供了更多的靈活性。

雖然你為此次實驗創(chuàng)建的服務(wù)單元通常是由定時器調(diào)用的,你也可以隨時使用 systemctl start myMonitor.service 命令去觸發(fā)它??梢栽谝粋€定時器中編寫多個維護任務(wù)的腳本;它們可以是 Bash 腳本或者其他 Linux 程序。你可以通過觸發(fā)定時器來運行所有的腳本來運行服務(wù),也可以按照需要執(zhí)行單獨的腳本。

我會在下篇文章中更加深入的探索 systemd 時間格式的用處。

我還沒有看到任何跡象表明 cron 和 at 將被廢棄。我希望這種情況不會發(fā)生,因為至少 at 在執(zhí)行一次性調(diào)度任務(wù)的時候要比 systemd 定時器容易的多。

感謝各位的閱讀,以上就是“如何使用 systemd 定時器代替 cron 作業(yè)”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對如何使用 systemd 定時器代替 cron 作業(yè)這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI