Crontab定时任务

1、开篇之意

什么是定时任务?定时任务的作用?举例:比如我们的手机闹钟。

下面全文篇幅会进入Linux系统定时任务的水文篇,Crontab是面向操作系统的定时任务,可能我们工作中还会接触到面向集群,面向项目的定时任务不或许那个应该有一个高大上的名字,恩就叫调度好了;原理都是相同,本文会从定时任务维度Crontab配置技巧相关重要文件排错技巧同时我们也会介绍一个案例,同时引出我们经常会遇到的错误,最后我们再来说说定时任务的安全。

全文使用的操作系统为CentOS7系列。

2、Crontab

2.1 Crontab安装

默认情况下所有系统几乎都预装了,不过这里我们还是走一个形式吧,我们通过yum进行安装:

sudo yum install crontabs -y

我们启动服务,并配置开机自启动:

sudo systemctl start crond
sudo systemctl enable crond

之后,我们可以通过查看状态,是否已经启动:

sudo systemctl status crond

2.2 Crontab时间维度

# .---------------- 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
# |  |  |  |  |
# *  *  *  *  * command to be executed

Crontab支持的维度有分钟小时月份其中月份和周可以用英文单词来表示,不过我们依然推荐用数字来表示,同时周位置上0和7表示的都是周末的意思。

同时也不要将顺序给弄错了。(分时天月周)

是的,你没有看错,Crontab不支持秒的维度,所以有秒的需求可以用别的方法了。

2.3 Crontab配置

上面我们已经说了定时任务的维度,接下来我么说说配置;配置定时任务有两种形式,不对应该是三种,那三种呢?

  1. 全局配置
  2. 基于用户交互式配置
  3. 基于用户非交互式的配置

2.3.1 全局配置

全局配置我们需要通过文本编辑工具编辑/etc/crontab这个文件,配置格式呢?

*  *  *  *  * user-name  command to be executed

前面的5个*代表的是时间维度,user-name表示使用那个用户来执行,最后就是跟上需要执行的命令了。

因为全局配置生产中用的很少,了解即可。

2.3.2 基于用户交互式配置

基于用户的交互式配置,系统帮我们内置了一个命令crontab, 它可以帮助我们完成这项工作,他有以下三个比较常用的参数:

-l    查看定时任务
-e    编辑定时任务
-u    指定用户

crontab的核心原理就是,打开一个配置文件使用vi的方式,同时在你保存的时候会帮你校验语法规则。

看到这里,这个工具真的是非常的强大,对也是生产之中用的最多的一种方式;那么crontab交互命令他的语法有什么不同呢?

*  *  *  *  * command to be executed

这里请注意看,软件省略了用户那一栏的选项,因为是基于用户的,默认情况下crontab以当前用户的身份进行配置定时任务。

2.3.3 基于用户非交互式配置

什么是基于用户非交互式的配置呢?答案就是我们直接修改相关的配置文件。

默认情况下,crontab会在/var/spool/cron目录下创建对应用户名的文件,里面则就是你配置的定时任务了,所以我们直接通过vim进行修改文件也是可以的。唯一的不足就是他不支持语法检查

这种方式的应用场景在呢? 集群统一管理,统一管理一个文件要比去交互式添加方便多,也更加灵活。

2.3.4 Crontab时间维度TAG

TAG是帮助我们更加灵活的书写时间的一种方式,我们常用的TAG有:

*    代表匹配所有
,    分隔符,比如0,30;如果配置在分钟级别上则表示半小时一次
-    连接段,比如17-19 等同于17,18,19
/n   除法因子,比如*/5 如果配置在分钟级别,则是每5分钟

上面的TAG可以用到任何一个时间维度上,但是请结合实际情况来时使用。

错误案例如下:

30 00 * * 9

周的时间维度上,怎么可能会出现超过维度的情况呢!

2.3.5 Crontab使用技巧

技巧一:给你的定时任务加日志

具体怎么加我就不阐述了

技巧二:扩展你的环境变量

默认情况下Crontab服务带的环境变量只有/bin/:/usr/bin完全不够用,如何扩展呢?可以在你的脚本前面重新导出你的环境变量即可。

示例:定时任务

# Sync time by init
* * * * * /bin/sh /server/scripts/sync_time.sh

脚本内容

#!/bin/bash
# Sync Time By Evan At 20181215

# load mod
#export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
source /etc/profile

#/usr/sbin/ntpdate ntp1.aliyun.com &>/dev/null
ntpdate ntp1.aliyun.com &>/dev/null
if [ $? -eq 0 ];then
    echo "`date +%F_%T` Sync Time Ok!" >>/tmp/sync_time.log
else
    echo "`date +%F_%T` Sync Time No!" >>/tmp/sync_time.log
fi

聪明的你一定发现了, 6行和7行都是扩展环境变量的一种方式,但是我更推荐于后者,直接导入系统模块。

2.3.6 配置定时任务的注意事项

加注释,加注释,加注释,重要的事情说三遍。

命令行测试完成后一定要复制,千万不要手敲非常容易出错。(哪怕你是大牛)

生产定时任务一定要经过专人审核。

记录日志。

以上就是我想说的注意事项了,配置一个健壮良好的定时任务就靠他了。

2.3.7 Crontab常用注意文件

你需要特殊注意的三个文件,准确的说是两个文件,一个文件夹:

/var/spool/cron
/etc/crontab
/etc/cron.deny

/var/spool/cron是存放基于用户的定时任务的目录,/etc/crontab存放的是全局的定时任务,/etc/cron.deny存放的是不允许用户执行定时任务的文件。

2.3.8 Crontab排错技巧

当你出现异常的时候,我这边给你提供如下几个排查方向。

  1. 检查Crontab服务是否启动
  2. 语法配置是否得当
  3. 查看日志
  4. 使用工具模拟执行时间
  5. 注意系统时间是否配置OK
  6. 查看服务日志

3、定时任务案例

3.1 系统时间同步案例

我们只展示配置语法,具体细节请自行调整

*/5 * * * * /bin/sh /server/scripts/sync_time.sh &>/dev/null

每5分钟,调用一次系统时间同步的定时任务。

3.2 系统备份

因为我们这里是定时任务,所以脚本内的细节不过多展示。

00 00 * * * /bin/sh /server/scripts/backup.sh &>/dev/null

每天凌晨调用备份脚本。

3.3 维护案例

场景如下,我们有一个用户叫做etluser,集群目前正在维护我们希望维护时间内相关定时任务不要执行,那我们如何做?

答案:我们将etluser用户写入到/etc/cron.deny文件中。

3.4 补充:常见的故障

故障一:环境变量问题,前面我们已经提到过了;

故障二:Crontab定时任务屏幕输出,调用MailTo发送邮件,产生大量小文件;解决方法,不要有屏幕输出即可

故障三:时间维度逻辑错误,比如: * 00 * * *

3.5 安全案例

系统中存在着大量的系统用户,有些黑客就利用这些黑客造就后门,后门的大多数支撑都依赖于定时任务,所以我们可以将系统用户加入到/etc/cron.deny文件中,来为我们的系统增加一份保障。

我们推荐的用户有:

daemon
bin
smtp
nuucp
listen
nobody
noaccess

总结

Crontab是一个面向系统的定时任务,他的缺点就是不支持秒,不过我相信90%的场景都已经满足了。话外提一下,所有的任务都应该有可以监控或者Check地方,比如网上的一个段子:数据备份三年,最后没有备份成功。

好了,如果大家看到这里有什么疑问或者改正的地方可以再下方留言。

原文地址:https://www.cnblogs.com/evan-blog/p/10128245.html