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

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

成都創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括陽(yáng)谷網(wǎng)站建設(shè)、陽(yáng)谷網(wǎng)站制作、陽(yáng)谷網(wǎng)頁(yè)制作以及陽(yáng)谷網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,陽(yáng)谷網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到陽(yáng)谷省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

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

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

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

操作系統(tǒng)維護(hù)的計(jì)時(shí)器

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

作為示例,我會(huì)查看一些我的主要工作站上的定時(shí)器,通過(guò)執(zhí)行 systemctl status *timer 命令來(lái)展示主機(jī)上的所有定時(shí)器。星號(hào)的作用與文件通配相同,所以這個(gè)命令會(huì)列出所有的 systemd 定時(shí)器單元。

[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.

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

  • 定時(shí)器的第一行有定時(shí)器名字和定時(shí)器目的的簡(jiǎn)短介紹

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

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

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

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

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

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

你也許有一些不一樣的定時(shí)器,取決于你的主機(jī)。

創(chuàng)建一個(gè)定時(shí)器

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

首先,創(chuàng)建一個(gè)運(yùn)行基礎(chǔ)東西的簡(jiǎn)單的服務(wù),例如 free 命令。舉個(gè)例子,你可能想定時(shí)監(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)建的最簡(jiǎn)單的服務(wù)單元了。現(xiàn)在我們查看一下服務(wù)狀態(tài)同時(shí)測(cè)試一下服務(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)會(huì)被發(fā)送到系統(tǒng)日志中,它保留了記錄供現(xiàn)在或者之后(直到某個(gè)時(shí)間點(diǎn))查看。(在本系列的后續(xù)文章中,我將介紹系統(tǒng)日志的記錄和保留策略)。專門(mén)查看你的服務(wù)單元的日志,而且只針對(duì)今天。-S 選項(xiàng),即 --since 的縮寫(xiě),允許你指定 journalctl 工具搜索條目的時(shí)間段。這并不代表你不關(guān)心過(guò)往結(jié)果 —— 在這個(gè)案例中,不會(huì)有過(guò)往記錄 —— 如果你的機(jī)器以及運(yùn)行了很長(zhǎng)時(shí)間且堆積了大量的日志,它可以縮短搜索時(shí)間。

[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ù)可以是單個(gè)程序、一組程序或者是一個(gè)腳本語(yǔ)言寫(xiě)的腳本。通過(guò)在 myMonitor.service 單元文件里的 [Service] 塊末尾中添加如下行可以為服務(wù)添加另一個(gè)任務(wù):

ExecStart=/usr/bin/lsblk

再次啟動(dòng)服務(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 定時(shí)器單元文件,添加如下代碼:

# 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 時(shí)間格式,*-*-* *:*:00,應(yīng)該會(huì)每分鐘觸發(fā)一次定時(shí)器去執(zhí)行 myMonitor.service 單元。我會(huì)在文章的后面進(jìn)一步探索 OnCalendar 設(shè)置。

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

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

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

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

一條結(jié)果立即就顯示出來(lái)了,下一條大概在一分鐘后出來(lái)。觀察幾分鐘日志,看看你有沒(méi)有跟我發(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.

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

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

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

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

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

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

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

AccuracySec=1us

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

  • usecus,µs

  • msec,ms

  • secondssecond,secs

  • minutes,minute,min,m

  • hours,hour,hrh

  • days,day,d

  • weeks,week,w

  • months,monthM(定義為 30.44 天)

  • years,year,y(定義為 365.25 天)

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

[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 目錄下部分定時(shí)器單元文件的完整內(nèi)容,看看它們是如何構(gòu)建的。

在本實(shí)驗(yàn)中不必讓這個(gè)定時(shí)器在啟動(dòng)時(shí)激活,但下面這個(gè)命令可以設(shè)置開(kāi)機(jī)自啟:

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

你創(chuàng)建的單元文件不需要是可執(zhí)行的。你同樣不需要啟用服務(wù),因?yàn)樗潜欢〞r(shí)器觸發(fā)的。如果你需要的話,你仍然可以在命令行里手動(dòng)觸發(fā)該服務(wù)單元。嘗試一下,然后觀察日志。

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

定時(shí)器類型

systemd 定時(shí)器還有一些在 cron 中找不到的功能,cron 只在確定的、重復(fù)的、具體的日期和時(shí)間觸發(fā)。systemd  定時(shí)器可以被配置成根據(jù)其他 systemd  單元狀態(tài)發(fā)生改變時(shí)觸發(fā)。舉個(gè)例子,定時(shí)器可以配置成在系統(tǒng)開(kāi)機(jī)、啟動(dòng)后,或是某個(gè)確定的服務(wù)單元激活之后的一段時(shí)間被觸發(fā)。這些被稱為單調(diào)計(jì)時(shí)器?!皢握{(diào)”指的是一個(gè)持續(xù)增長(zhǎng)的計(jì)數(shù)器或序列。這些定時(shí)器不是持久的,因?yàn)樗鼈冊(cè)诿看螁?dòng)后都會(huì)重置。

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

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

Table 1: systemd 定時(shí)器定義

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

日歷事件格式

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

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

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

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

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

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

Table 2: OnCalendar 事件時(shí)間格式例子

測(cè)試日歷格式

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

首先,看看未來(lái)沒(méi)有時(shí)間的日(注意 Next elapse 和 UTC 的時(shí)間會(huì)根據(jù)你當(dāng)?shù)貢r(shí)區(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)在添加一個(gè)時(shí)間,在這個(gè)例子中,日期和時(shí)間是當(dāng)作無(wú)關(guān)的部分分開(kāi)解析的:

[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]#

為了把日期和時(shí)間當(dāng)作一個(gè)單元來(lái)分析,可以把它們包在引號(hào)里。你在定時(shí)器單元里 OnCalendar= 時(shí)間格式中使用的時(shí)候記得把引號(hào)去掉,否則會(huì)報(bào)錯(cuò):

[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)在我們測(cè)試下 Table2 里的例子。我尤其喜歡最后一個(gè):

[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]#

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

[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)該為你提供了足夠的信息去開(kāi)始測(cè)試你的 OnCalendar 時(shí)間格式。systemd-analyze 工具可用于其他有趣的分析,我會(huì)在這個(gè)系列的下一篇文章來(lái)探索這些。

總結(jié)

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

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

我會(huì)在下篇文章中更加深入的探索 systemd 時(shí)間格式的用處。

我還沒(méi)有看到任何跡象表明 cron 和 at 將被廢棄。我希望這種情況不會(huì)發(fā)生,因?yàn)橹辽?nbsp;at 在執(zhí)行一次性調(diào)度任務(wù)的時(shí)候要比 systemd 定時(shí)器容易的多。

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

網(wǎng)站名稱:如何使用systemd定時(shí)器代替cron作業(yè)
分享網(wǎng)址:http://muchs.cn/article34/ipidse.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、企業(yè)網(wǎng)站制作、定制開(kāi)發(fā)、網(wǎng)站收錄、定制網(wǎng)站搜索引擎優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司