l23.Linux系统定时任务Cron(d)服务应用实践(一)

922 阅读18分钟

“ 本文正在参加「金石计划 . 瓜分6万现金大奖」 ”

13.1 Cron(d)介绍

13.1.1 什么是Cron?

Cron是Linux系统中以后台进程模式周期性执行命令或指定程序任务的服务软件。默认情况下,安装完Linux操作系统之后,Cron服务软件便会启动,服务对应的进程名字为Crond,Crond服务会定期(默认每分钟检查一次)检查系统中是否有需要执行的任务工作计划。如果有,则会根据其预先设定的定时任务规则自动执行该定时任务工作。这个Crond定时任务服务就相当于我们平时使用的闹钟(或手机闹钟)。

Linux系统中的Cron定时任务执行的最快频率是每分钟执行一次,因此如果是需要以秒为单位执行的计划任务,Cron就不适用了。面对这种情况,在工作中可以编写Shell脚本,然后作为守护程序执行。以下是一个每秒种执行一次任务的脚本:

[root@centos7 ~]# cat cron.sh
while true
do
    echo "I am neteagle teacher."
    sleep 1
done

提示:当然也有秒级定时任务人员,但是用途不多,因此,读者不需要过多涉及。

13.1.2 为什么要使用Crond定时任务?

前文讲解过,Linux运维工程师的职责之一就是保障数据安全,那么,其日常工作任务之一就是不断地对数据进行备份,而很多时候白天系统业务繁忙,因此数据备份的工作只能放到晚上执行,例如,网站数据库数据以及用户上传的图片、文件和程序文件等,一般需要每天晚上做一次备份。如果没有定时任务工具,管理员就得每天半夜爬起来,登录到系统中手工执行任务计划,直到执行完才能去睡觉。执行任务的过程可能会持续好几个小时,这样一来,一个晚上管理员就都😩睡觉了,这样显然是不行的。那么有什么办法可以解决这个周期性地执行任务计划的问题呢?

这就需要Linux系统的定时任务Cron工具了,Cron工具可以很好地帮我们完成需要重复的、周期性地、自动备份等运维工作。

13.1.3 不同系统的定时任务种类介绍

13.1.3.1 Windows系统的定时任务

在继续讲解Linux的定时任务之前,我们先来看一看Windows的任务计划,Windows系统也是有定时任务计划工具的。

这里以Windows7系统为例进行说明,选择“开始”→

“开始”→“附件”→“系统工具”→“任务计划程序”,就会弹出如图13-1所示的窗口。

t13-1.png

图13-1 Windows 7的任务计划图

图13-2所示的是设定好的,每天晚上自动关机的定时任务。

t13-2.png

图13-2 每天晚上自动关机的设置图解

更多信息可见:wenku.baidu.com/view/174cb0…

13.1.3.2 Linux系统下的定时任务软件

严格地说,Linux系统下的定时任务软件还真不少,例如,at、Cron和anacron等,下面分别来简单介绍一下。

  • at定时任务软件(依赖于atd服务)适合于仅执行一次就结束的调度任务工作。例如,某天夜里需要处理一个工作任务,仅仅是这一天的夜里,对于这种突发性的工作任务,那就可以使用该软件。要使得at这个软件设定的配置生效,还需要提前启动一个名为atd的服务才行,这个工具在工作中的使用需求很少,读者简单了解一下即可。
  • Cron定时任务软件依赖于Crond服务。正如前面所说,通过crontab命令可以配置周期性执行的定时任务工作计划,例如,每5分钟做一次服务器时间同步。要使得crontab命令设定的配置生效,还需要事先启动一个服务Crong才行。这个Cron工具(对应的crontab命令以及依赖的Crond服务)就是运维工程师在生产工作中最常使用的工具,请大家务必掌握。
  • anacron定时任务软件主要是为非7x24小时开机的服务器准备的,anacron并不能指定具体时间执行任务工作,而是以天为周期或者在系统每次开机后执行任务工作。它会检测服务器停机期间应该执行但是并没有进行的任务工作,并将该任务执行一遍。

13.1.3.3 Linux系统定时任务Cron(d)

在Linux系统中,Cron是定时任务的软件名,Crond是服务进程名,而crontab命令则是用来设置定时任务规则的配置命令。

为例更好地理解和学习Cron定时任务,本书将Cron定时任务人工划分为用户定时任务和系统定时任务计划两类,分别阐述如下。

(1)用户定时任务计划

Crond服务在工作时会以分钟为单位查看/car/spool/cron路径下以系统用户名的定时任务文件,以确定是否有需要执行的任务计划。如果有,就会将定时任务调度到内存中执行,笔者将这部分文件称为用户定时任务文件,使用crontab命令编辑的文件最终都会以当前用户名作为文件名存在于/var/spool/cron路径下。

如果是系统管理员或某个普通用户定期要做的任务工作,例如每隔5分钟与互联网上的时间服务器进行一次时间同步,每天晚上0点备份网站站在数据以及数据库数据,就可以使用crontab命令配置在/var/spool/cron路径下。

(2)系统定时任务计划

Crond服务在工作时除了查看/var/spool/cron下的定时任务文件之外,还会查看/etc/cron.d目录以及/etc/anacrontab下的文件内容,里面通常是每天、每周或每月需要执行的任务,如果有需要执行的任务则会执行,系统定时任务的路径通常如下:

[root@centos7 ~]# ll /etc |grep cron
-rw-------.  1 root root      541 Aug  9  2019 anacrontab
drwxr-xr-x.  2 root root       36 Oct  1 16:17 cron.d   #系统定时任务的目录。
drwxr-xr-x.  2 root root       57 Oct 10 19:02 cron.daily   #按天轮询配置的目录。
-rw-------.  1 root root        0 Aug  9  2019 cron.deny
drwxr-xr-x.  2 root root       22 Oct  1 16:05 cron.hourly  #按小时轮询配置的目录。
drwxr-xr-x.  2 root root        6 Jun 10  2014 cron.monthly #按月轮询配置的目录。
-rw-r--r--.  1 root root      451 Jun 10  2014 crontab
drwxr-xr-x.  2 root root        6 Jun 10  2014 cron.weekly  #按周轮询配置的目录。

特别注意:系统路径下的定时任务配置格式与前文讲解的用户定时任务的配置格式是不同的。

Crond服务除了执行用户定时任务计划(/var/spool/cron目录)以外,还会周期性地自动执行与操作系统相关的定时任务工作,例如轮询系统日志、备份系统数据、清理系统缓存等,这些任务无需我们人为干预。示例代码如下:

[root@centos7 ~]# ll /var/log/messages* #Linux系统的日志被自动轮询,以时间结尾。
-rw-------. 1 root root  916099 Oct 16 20:50 /var/log/messages
-rw-------. 1 root root 2272408 Oct  8 13:17 /var/log/messages-20201008
-rw-------. 1 root root 1144024 Oct 11 14:36 /var/log/messages-20201011
[root@centos7 ~]# ll /var/log/secure*
-rw-------. 1 root root 21799 Oct 16 18:40 /var/log/secure
-rw-------. 1 root root 36582 Oct  8 13:07 /var/log/secure-20201008
-rw-------. 1 root root 15175 Oct 11 13:16 /var/log/secure-20201011

类似于上述的日志轮询工作就是由系统自身来完成的,不需要系统管理员来设置,命令如下:

[root@centos7 ~]# ll /etc/logrotate.conf /etc/cron.daily/logrotate 
-rwx------. 1 root root 219 Apr  1  2020 /etc/cron.daily/logrotate  #每天执行的日志轮询定时任务配置。
-rw-r--r--. 1 root root 662 Jul 31  2013 /etc/logrotate.conf    #日志轮询切割配置文件。

本章讨论的重点是Cron的用户定时任务计划内容,当然,读者也可以自行学习系统任务计划相关的内容,从而让工作中的任务计划按系统任务计划的格式执行也是可以的(此部分内容不是必须的,也不是本文讲解的重点)。

13.2 用户定时任务Cron(d)使用说明

13.2.1 crontab定时任务编辑命令语法

在Linux运维工作中,通常使用crontab命令编辑定时任务,crontab的相关参数及说明如表13-1所示。

表13-1 crontab的相关参数及说明

b13-1.png

特别强调:-i、-r参数在生产中很少使用,另外,使用crontab命令编辑的文件实际上就是在操作“/var/spool/cron/当前用户名”这样的文件。

13.2.2 使用定时任务权限及配置文件说明

表13-2所示的是定时任务软件相关文件及路径说明。

表13-2 定时任务软件相关文件及路径说明

b13-2.png

13.2.3 以用户定时任务crontab命令编辑内容格式

默认情况下,待用户建立定时任务规则之后,该规则所记录的对应配置文件将会存在于/var/spool/cron中,其crontab配置文件对应的文件名与登录的用户名应一致,例如,root用户的定时任务配置文件为/var/spool/cron/root。

利用crontab命令编写定时任务的书写格式很简单,规则一般可分为6个段(每个段之间均通过空格来分隔),前5段为时间设定段,第6段为所要执行的命令或脚本任务段。

用户定时任务编写基本格式如下:

01 * * * * cmd
02 4 * * * cmd

提示:

1)cmd为要执行的命令或脚本,例如/bin/sh/server/scripts/neteagle.sh。

2)每个列之间必须要有一个空格,可以存在多个空格。

13.2.3.1 用户定时任务编写语法中时间段的含义

使用crontab命令编辑的用户定时任务中的时间段对应的含义如表13-3所示。

表13-3 crontab命令编辑的用户定时任务时间段说明

b13-3.png

实践记忆口诀:分时日月周。取值范围记忆:正常日期时间范围。

13.2.3.2 用户定时任务编写语法中特殊字符的含义

在使用crontab命令编辑的用户定时任务的语法中,除了时间段以外,还会包含很多特殊字符应用,对应的含义如表13-4所示。

表13-4 用户定时任务编写语法中的特殊字符及含义

b13-4.png

13.2.4 crontab命令编辑的定时任务依赖服务说明

crontab命令编辑的定时任务依赖于crond服务,下面来看一下它的运行情况,示例代码如下:

[root@centos7 ~]# systemctl status crond    #查看Cron定时任务服务启动状态。
● crond.service - Command Scheduler
#下面的enabled说明开机Crond为自启动,running为当前启动状态。
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2020-10-16 13:19:50 CST; 8h ago
 Main PID: 954 (crond)
   CGroup: /system.slice/crond.service
           └─954 /usr/sbin/crond -n
​
Oct 16 13:19:50 centos7 systemd[1]: Started Command Scheduler.
Oct 16 13:19:50 centos7 crond[954]: (CRON) INFO (RANDOM_DELAY wi...)
Oct 16 13:19:55 centos7 crond[954]: (CRON) INFO (running with in...)
Hint: Some lines were ellipsized, use -l to show in full.
[root@centos7 ~]# systemctl restart crond
#定时任务重启命令。

特别强调:

1)在编辑定时任务文件之后,无须重启定时任务,Crond会自动检查更改的变化。

2)当定时任务不能正确执行时,请查看定时任务日志文件(/var/log/cron)以获取故障信息。

13.3 用户定时任务Cron实例说明

下面来看一下用户定时任务Cron的使用实例,实例代码如下:

命令实例1: */1 * * * * /bin/sh /scripts/data.sh

在本例中,除了数字与命令脚本之外,还使用到了符号“ ”, 号的意思是“每一”。

第一列的意思为分钟,特殊符号“/”表示每隔的意思,即每隔一分钟执行一次/bin/sh /scripts/data.sh程序。

命令实例2: 30 3,12 * * * /bin/sh /scripts/netegalge.sh

在本例中,第一列为30,表示30分钟;第二列为“3,12”,表示3点和12点,此定时任务的意思是每天凌晨3点和中午12点的半点时刻(或描述为每天凌晨3:30和中午12:30)执行一次/scripts/netegalge.sh脚本任务。

命令实例3: 30 */6 * * * /bin/sh /scripts/neteagle.sh

在本例中,第一列为30,表示30分钟;第二列“*/6”代表每6个小时,相当于就是6、12、18、24的作用。此定时任务的意思是每隔6个小时的半点时刻执行一次/scripts/neteagle.sh脚本任务。

命令实例4: 30 8-12/2 * * * /bin/sh /scripts/neteagle.sh

在本例中,其中的第一列为30,表示30分钟;第二列的“8-12/2”代表在早晨8点到下午18点之间每隔2小时,也相当于是将8、10、12、14、16、18单独列出。

那么,此定时任务的意思就是早晨8点到下午18点之间,每隔2个小时的半点时刻执行一次/scripts/neteagle.sh。

命令实例530 21 * * * /application/apache/bin/apachectl graceful

本例表示每晚21:30重启Apache。

命令实例645 4 11022 * * /application/apache/bin/apachectl graceful

本例表示每月1、10、22的凌晨4:45分重启一次Apache。

命令实例7: 10 1 * * 6,0 /application/apache/bin/apachectl graceful

本例表示每周六、周日的凌晨1:10分重启一次Apache。

命令实例80,30 18-23 * * * /application/apache/bin/apachectl graceful

本例表示在每天18:00至23:00之间每隔30分钟重启一次Apache。

命令实例900 */1 * * * /application/apache/bin/apachectl graceful

本例表示每隔一个小时整点重启一次Apache。

命令实例10: * 2300-07/1 * * * /application/apache/bin/apachectl graceful

本例并不是表示晚上23点和早上0~7点之间每隔一小时重启一次Apache。

需要说明的是,以上结果是不规范的,也是不对的。大家想想为什么?

以上定时任务的第一列为“*”,表示每分钟都执行一次任务,即晚上23点和早上0~7点之间每一分钟都重启一次Apache,很可怕吧。

命令实例11: 00 11 * 4 1-3 /application/apache/bin/apachectl graceful

本实例表示4月的每周一到每周三的商务11点整重启一次Apache。

命令实例12: 30 09 * * 0 去上课

本例表示每周日上午9:30去上课,这是上课评率。

命令实例13: 30 08 * * * 去上课

本例表示每天上午8:30去上课,这是上课评率。

通过上述13个例子,相信读者已经能够理解定时任务的配置规则了。

13.4 生产环境下用户Cron配置专业实践案例

前文是通过定时任务规则来理解定时任务计划,下文是根据需求来设定定时任务规则的案例,读者可以自己解答一下,看是否搞懂了。

范例13-1: 每分钟打印一次neteagle字符串到"/server/log/neteagle.log"中。

新手编辑定时任务时很容易出错,因此,一定要养成一个号的编辑习惯才行,解答本题的详细步骤如下。

第一步: 先在命令行实现要处理的任务,这一步很重要,很多新手直接编写定时任务,结果出现了各种错误,在练习场景下还好,若是在工作中,可能就会错过任务执行时间了。在命令行下进行测试的步骤如下:

[root@centos7 ~]# echo neteagle >>/server/log/neteagle.log  #命令行执行,将neteagle追加到文件里。
-bash: /server/log/neteagle.log: No such file or directory  #报错,提示每月文件或目录。
[root@centos7 ~]# mkdir -p /server/log  #创建对应不存在的目录。
[root@centos7 ~]# echo neteagle >>/server/log/neteagle.log
[root@centos7 ~]# cat /server/log/neteagle.log  #查看执行后的结果。
neteagle

第二步: 在Linux命令行执行crontab -e。进入vi编辑文本的状态之后,输入如下内容:

[root@centos7 ~]# crontab -e
#print my name to log by neteagle at 202010
* * * * * echo neteagle >>/server/log/neteagle.log
:wq

第三步: 保存,查看编辑完的定时任务配置。以下是具体命令:

[root@centos7 ~]# crontab -l |head -2
#print my name to log by neteagle at 202010
* * * * * echo neteagle >>/server/log/neteagle.log

第四步: 观察生效情况。以下是具体命令:

[root@centos7 ~]# tail -f /server/log/neteagle.log 
neteagle
neteagle
neteagle

提示:思考以及配置的规范过程比答案更重要,如果出现问题,请查看/var/log/cron排错。

本示例的知识小结具体如下。

  • 先确认Crond服务进程是否开启。

  • 书写定时任务规则前应尽量先写注释,以方便自己以及同事阅读。

  • 这里的/server/log目录必须事先存在才能出结果,因此,在命令行测试执行成功很重要。

  • 定时任务中的所有路径(包含文件和命令等的路径)都尽量使用绝对路径(本题中不加echo也可以)。

  • 如果命令中有重定向符号等,那么结尾不要再加>/dev/null 2>&1,否则会出错。

  • 注意,定时任务的书写操作步骤具体如下。

    1)先在命令行调试成功。

    2)再将命令复制到定时任务配置里。

    3)然后保存,并使用tail -f测试观察结果。

    4)如果遇到问题,则可根据输出以及定时任务日志/var/log/cron文件内容排错。

    范例13-2: 让服务器时间每5分钟与互联网时间做一次同步。

    本题的解答思路比较简单,下面直接给出答案如下:

[root@centos7 ~]# crontab -e
#time sync by neteagle at 20201017
*/5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com &>/dev/null
*/5 * * * * /usr/sbin/ntpdate ntp3.aliyun.com &>/dev/null
:wq
[root@centos7 ~]# crontab -l |tail -3
#time sync by neteagle at 20201017
*/5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com &>/dev/null
*/5 * * * * /usr/sbin/ntpdate ntp3.aliyun.com &>/dev/null

提示: CentOS 7.6默认没有安装ntpdate命令,需要事先执行yum安装,命令是yum install -y ntpdate。

服务器的时间同步很重要,因此,在工作中最好是配置两个不同地址的同步任务,在互联网中,可用ntp时间服务器地址信息查看老男孩的博客地址:

blog.51cto.com/oldboy/2109…

范例13-3: 每天晚上0点,将站点目录/var/www/html下的内容打包备份到/data目录下,并且要求每次生成不同的备份包名。

第一步: 确认要备份的数据目录和备份的目的地路径是否存在,如果不存在就创建一个,以便测试。以下是具体的操作步骤:

[root@centos7 ~]# ll -d /var/www/html /data
ls: cannot access /var/www/html: No such file or directory  #目录都不存在。
ls: cannot access /data: No such file or directory
[root@centos7 ~]# mkdir -p /var/www/html /data  #创建目录。
[root@centos7 ~]# touch /var/www/html/neteagle{1..5}.txt    #同时创建几个文件。
[root@centos7 ~]# ls /var/www/html/
neteagle1.txt  neteagle3.txt  neteagle5.txt
neteagle2.txt  neteagle4.txt

第二步: 备份数据,一般是采用压缩打包的形式。以下是命令行测试:

[root@centos7 ~]# cd /var/www/  #打压缩包,最好是到备份数据目录的上一级目录打包。
[root@centos7 /var/www]# tar zcvf /data/bak_$(date +%F).tar.gz ./html   #带日期打包,目的是不同次备份生成不同的文件。
./html/
./html/neteagle1.txt
./html/neteagle2.txt
./html/neteagle3.txt
./html/neteagle4.txt
./html/neteagle5.txt
[root@centos7 /var/www]# ll /data
-rw-r--r--. 1 root root 182 Oct 17 14:41 bak_2020-10-17.tar.gz

第三步: 将测试成功的命令行写入到文件里执行,。注意,定时任务执行的命令最好是以Shell脚本的形式来执行,这样可以规避很多潜在的运行错误,例如,由“%“导致的错误,代码如下:

[root@centos7 /var/www]# mkdir -p /server/scripts   #规范定时任务脚本存放的路径。 
[root@centos7 /var/www]# cd /server/scripts/    #切换到路径下。
[root@centos7 /server/scripts]# vim bak.sh  #编辑脚本。
cd /var/www/&&\ #表示本条命令成功之后再执行下面的tar命令,\表示换行。
/bin/tar zcf /data/bak_$(date +%F).tar.gz ./html    #注意:这里去掉了-v参数,即不输出信息,打包的文件名中使用了日期变量,这样才能按天生成不同的压缩包文件。
:wq
[root@centos7 /server/scripts]# rm -f /data/bak*
#删除以前生成的文件。
[root@centos7 /server/scripts]# /bin/sh /server/scripts/bak.sh 
-rw-r--r--. 1 root root 182 Oct 17 14:43 bak_2020-10-17.tar.gz

第四步:编写定时任务。在Linux命令行执行crontab -e,进入vi编辑状态之后,输入以下内容:

[root@centos7 /server/scripts]# crontab -e
#backup size dir by neteagle at 20201017    #清晰的注释。
00 00 * * * /bin/sh /server/scripts/bak.sh >/dev/null 2>&1  #复制命令行脚本内容到这里,结尾要加>/dev/null 2>&1,将所有输出定向到空。
:wq
[root@centos7 /server/scripts]# crontab -l |tail -2
#backup size dir by neteagle at 20201017
00 00 * * * /bin/sh /server/scripts/bak.sh >/dev/null 2>&1

针对以上两个定时任务的实际应用例子,可以总结一下企业生产环境中定时任务的专业编写规范和操作步骤。