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