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

在Schedule中輸入cron表達式來配置定時任務。
Jenkins也可以創建多個定時,比如在每個工作日的9:30和每周五22:30構建:
30 9 * * 1-5
30 22 * * 5