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配置
上面我们已经说了定时任务的维度,接下来我么说说配置;配置定时任务有两种形式,不对应该是三种,那三种呢?
- 全局配置
- 基于用户交互式配置
- 基于用户非交互式的配置
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排错技巧
当你出现异常的时候,我这边给你提供如下几个排查方向。
- 检查Crontab服务是否启动
- 语法配置是否得当
- 查看日志
- 使用工具模拟执行时间
- 注意系统时间是否配置OK
- 查看服务日志
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地方,比如网上的一个段子:数据备份三年,最后没有备份成功。
好了,如果大家看到这里有什么疑问或者改正的地方可以再下方留言。