定時(shí)任務(wù)的使用場(chǎng)景非常廣泛,比如定時(shí)發(fā)送郵件,定時(shí)清理日志等等,在持續(xù)集成中,可以定時(shí)地觸發(fā)測(cè)試任務(wù),比如希望在每天晚上下班時(shí)間執(zhí)行自動(dòng)化用例。本文通過(guò)介紹linux cron定時(shí)來(lái)了解cron定時(shí)相關(guān)概念。
Linux Crontab 定時(shí)任務(wù)
cron來(lái)源于希臘語(yǔ)chronos,意思是時(shí)間。在類(lèi)Unix的操作系統(tǒng)中,可以使用cron 服務(wù)器來(lái)實(shí)現(xiàn)定時(shí)執(zhí)行任務(wù)。crontab文件存放cron指令,執(zhí)行周期命令的守護(hù)進(jìn)程crond負(fù)責(zé)激活這些任務(wù),定期檢查是否有任務(wù)執(zhí)行。
crond 服務(wù)
crond 服務(wù)是用來(lái)執(zhí)行周期任務(wù)或等待處理某些事件的一個(gè)守護(hù)進(jìn)程,crontab 命令需要 crond 服務(wù)支持。centos7中一般是默認(rèn)安裝的,可以使用 rpm 命令查看是否安裝:
$ rpm -qa | grep crontab
crontabs-1.11-6.20121102git.el7.noarch
查看crond 服務(wù)狀態(tài):
# centos7
systemctl status crond.service
# centos6
service crond status
啟動(dòng)crond 服務(wù):
# centos7
systemctl start crond.service
# centos6
service crond start
停止crond 服務(wù):
# centos7
systemctl stop crond.service
# centos6
service crond stop
重啟crond 服務(wù):
# centos7
systemctl restart crond.service
# centos6
service crond restart
重載crond 服務(wù):
# centos7
systemctl reload crond.service
# centos6
service crond reload
crontab相關(guān)文件
cron 服務(wù)主要包括以下文件目錄:
- /var/spool/cron:用戶(hù)定義的crontab文件存放目錄
- /etc/cron.d:存放要執(zhí)行的crontab文件或腳本
- /etc/crontab:系統(tǒng)任務(wù)調(diào)度的配置文件
- /etc/anacrontab:anacron配置文件
- /etc/cron.deny:列出不允許使用crontab命令的用戶(hù)
- /etc/cron.daily:每天執(zhí)行一次的腳本
- /etc/cron.hourly:每小時(shí)執(zhí)行一次的腳本
- /etc/cron.monthly:每月執(zhí)行一次的腳本
- /etc/cron.weekly:每星期執(zhí)行一次的腳本
/etc/crontab文件負(fù)責(zé)管理和維護(hù)任務(wù):
$ cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
其中:
- SHELL變量指定系統(tǒng)使用的shell版本
- PATH指定系統(tǒng)執(zhí)行命令的路徑
- MAILTO指定郵件發(fā)送的用戶(hù),如果為root,郵件會(huì)發(fā)送到/var/spool/mail/root文件中
cron表達(dá)式
用戶(hù)定義的crontab文件保存在 /var/spool/cron 目錄中,每個(gè)crontab任務(wù)以創(chuàng)建者的名字命名。crontab文件中每一行都代表一項(xiàng)任務(wù),每條命令包括6個(gè)字段,前5個(gè)代表時(shí)間,第6個(gè)字段是要執(zhí)行的命令。
五顆星:* * * * *
- 第1顆星:分鐘 minute,取值 0~59;
- 第2顆星:小時(shí) hour,取值 0~23;
- 第3顆星:天 day,取值 1~31;
- 第4顆星:月 month,取值 1~12;
- 第5顆星:星期 week,取值 0~7,0 和 7 都表示星期天。
可以使用4種操作符:
- * :當(dāng)前代表的所有取值范圍內(nèi)的數(shù)字
- /:需要間隔的數(shù)字
- -:某個(gè)區(qū)間,比如1-3表示1, 2, 3
- ,:分散的數(shù)字,可以不連續(xù),比如1, 3, 5
下面舉幾個(gè)例子:
# 每5分鐘構(gòu)建一次
H/5 * * * *
# 每2小時(shí)構(gòu)建一次
H H/2 * * *
# 每天8點(diǎn)到22點(diǎn),每2小時(shí)構(gòu)建一次
H 8-22/2 * * *
# 每天8點(diǎn),22點(diǎn)各構(gòu)建一次
H 8,22 * * *
crontab命令
crontab 命令用來(lái)配置定時(shí)任務(wù),語(yǔ)法如下:
crontab [options] file
crontab [options]
常用options:
- -u <user> :定義用戶(hù)
- -e:編輯 crontab表
- -l: 列出用戶(hù)crontab表
- -r:刪除用戶(hù)crontab表
- -i:刪除提示
- -n <hostname> 設(shè)置用戶(hù)crontab主機(jī)名
- -c:獲取運(yùn)行用戶(hù)crontab的主機(jī)名
- -s:selinux 上下文
- -x <mask> :開(kāi)啟調(diào)試
crontab定時(shí)示例
先寫(xiě)一個(gè)用于采集CPU性能信息的腳本(cpu_Perf.sh):
#!/bin/bash
mpstat -P ALL 1 2 >> /var/cron/perf.log
下面來(lái)添加一個(gè)定時(shí)任務(wù):
執(zhí)行 命令crontab -e ,輸入下面的cron表達(dá)式,每分鐘執(zhí)行一次CPU性能采集腳本:
* * * * * /var/cron/cpu_Perf.sh
保存。命令保存到了 /var/spool/cron/ 目錄下的root文件中(當(dāng)前用戶(hù)為root):
$ cat /var/spool/cron/root
* * * * * /var/cron/cpu_Perf.sh
$ crontab -l
* * * * * /var/cron/cpu_Perf.sh
保存成功后,每一分鐘就會(huì)執(zhí)行一次腳本。
Linux anacron 定時(shí)任務(wù)
如果服務(wù)器關(guān)機(jī)或者無(wú)法運(yùn)行任務(wù),定時(shí)任務(wù)就不會(huì)執(zhí)行,服務(wù)器恢復(fù)后,定時(shí)任務(wù)不會(huì)執(zhí)行沒(méi)有執(zhí)行的定時(shí)任務(wù)。這種場(chǎng)景下可以使用anacron命令,它與crond功能相同,增加了執(zhí)行被跳過(guò)任務(wù)的功能。一旦服務(wù)器啟動(dòng),anacron就會(huì)檢查配置的定時(shí)任務(wù)是否錯(cuò)過(guò)了上一次執(zhí)行,如果有,將立即運(yùn)行這個(gè)任務(wù),且只運(yùn)行一次(不管錯(cuò)過(guò)了多少個(gè)周期)。
也就是說(shuō), anacron 是用來(lái)保證由于系統(tǒng)原因?qū)е洛e(cuò)過(guò)的定時(shí)任務(wù)可以在系統(tǒng)正常后執(zhí)行的服務(wù)。
anacron命令
可以使用 anacron 命令來(lái)管理 anacron 服務(wù),語(yǔ)法格式如下:
anacron [options] [job] ...
anacron -T [-t anacrontab-file]
options選項(xiàng):
- -s:串行調(diào)用任務(wù)
- -f:強(qiáng)制執(zhí)行任務(wù),忽略設(shè)置的周期
- -n:沒(méi)有delay執(zhí)行任務(wù),隱含調(diào)用了-s參數(shù)
- -d:把信息輸出到標(biāo)準(zhǔn)輸出設(shè)備和系統(tǒng)日志中
- -q:禁止向標(biāo)準(zhǔn)輸出發(fā)送消息,只能和-d選項(xiàng)配合使用。
- -u:更新時(shí)間戳但不執(zhí)行任務(wù)
- -V:打印版本信息
- -h:打印幫助信息
- -t <file> :使用指定的配置文件,忽略默認(rèn)的/etc/anacrontab文件。
- -T:Anacrontab測(cè)試
- -S <dir>:指定存放timestamp文件的路徑
job 是 /etc/anacrontab 文件中定義的工作名 job-identifier
anacron執(zhí)行過(guò)程
下面來(lái)介紹一下anacron的執(zhí)行過(guò)程:
1、根據(jù)腳本需要執(zhí)行的頻率,將腳本安裝到/etc/cron.[hourly|daily|weekly|monthly] 目錄中:
/etc/cron.hourly
/etc/cron.daily
/etc/cron.monthly
/etc/cron.weekly
2、crond 服務(wù)會(huì)執(zhí)行/etc/cron.d/0hourly 中指定的cron 任務(wù),
$ cat /etc/cron.d/0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly
每小時(shí)運(yùn)行一次 run-parts 程序,而 run-parts 程序執(zhí)行 /etc/cron.hourly 中的所有的shell腳本。
/etc/cron.hourly 目錄中包含 0anacron 腳本:
$ ls /etc/cron.hourly
0anacron mcelog.cron
3、 0anacron 腳本通過(guò) /etc/anacrontab 配置文件來(lái)運(yùn)行anacron程序。
$ cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22
#period in days delay in minutes job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
7 25 cron.weekly nice run-parts /etc/cron.weekly
@monthly 45 cron.monthly nice run-parts /etc/cron.monthly
- RANDOM_DELAY=45 :表示最大隨機(jī)延遲時(shí)間為45分鐘。
- START_HOURS_RANGE=3-22 : 執(zhí)行的時(shí)間范圍為03:00—22:00
/etc/anacrontab 配置文件執(zhí)行cron.[daily|weekly|monthly] 目錄中的可執(zhí)行文件。
anacron的監(jiān)測(cè)周期為每天、每周和每月,每天執(zhí)行一次/etc/cron.daily 目錄中的程序,每周執(zhí)行一次 /etc/cron.weekly 中的程序,每月執(zhí)行一次 /etc/cron.monthly 中的程序。
anacron不能在指定某個(gè)時(shí)間運(yùn)行某個(gè)程序,它的設(shè)計(jì)目的是在特定的時(shí)間間隔運(yùn)行某個(gè)程序,例如每天,每周日或者每月第一天的03:00運(yùn)行某個(gè)程序。如果因?yàn)槟撤N原因(關(guān)機(jī)或者服務(wù)器異常)沒(méi)有執(zhí)行,anacron會(huì)在服務(wù)器正常后運(yùn)行一次錯(cuò)過(guò)的執(zhí)行。
那么,anacron 是如何判斷這些定時(shí)任務(wù)錯(cuò)過(guò)了執(zhí)行呢?
其實(shí)是通過(guò)讀取上次執(zhí)行 anacron 的時(shí)間記錄文件,通過(guò)兩個(gè)時(shí)間的差值判斷是否超過(guò)指定間隔時(shí)間(1天、1周和1月)。
/var/spool/anacron/ 目錄中的 cron.[daily|weekly|monthly] 文件記錄了上一次執(zhí)行 cron任務(wù) 的時(shí)間:
$ ls /var/spool/anacron/
cron.daily cron.monthly cron.weekly
$ cat /var/spool/anacron/cron.daily
20211123
cron表達(dá)式應(yīng)用
前面介紹了在Linux中通常用 crond 服務(wù)來(lái)實(shí)現(xiàn)任務(wù)定時(shí)執(zhí)行,在很多場(chǎng)景都會(huì)用到定時(shí)任務(wù),比如定時(shí)提醒,定時(shí)發(fā)送郵件等。比如Python中可以使用APScheduler庫(kù)執(zhí)行定時(shí)任務(wù),JAVA可以使用Quartz框架實(shí)現(xiàn),Go語(yǔ)言使用 github.com/robfig/cron 包。
在持續(xù)測(cè)試平臺(tái)Jenkins中經(jīng)常會(huì)配置定時(shí)執(zhí)行任務(wù),下面簡(jiǎn)單介紹一下Jenkins定時(shí)構(gòu)建配置方法。
Jenkins定時(shí)構(gòu)建
在配置Jenkins任務(wù)時(shí),構(gòu)建定時(shí)任務(wù)主要有兩種形式:
- 一種是配置周期觸發(fā)(Build periodically),在特定時(shí)間進(jìn)行自動(dòng)觸發(fā)測(cè)試流程。
- 第二種是Poll SCM:定時(shí)檢查源碼變更,如果有更新就checkout新的代碼下來(lái),然后執(zhí)行構(gòu)建動(dòng)作。
在【Build Triggers】中選擇 Build periodically 或者 Poll SCM
在Schedule中輸入cron表達(dá)式來(lái)配置定時(shí)任務(wù)。
Jenkins也可以創(chuàng)建多個(gè)定時(shí),比如在每個(gè)工作日的9:30和每周五22:30構(gòu)建:
30 9 * * 1-5
30 22 * * 5
--THE END--