定时任务

Posted だā简ゑ箪ャ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了定时任务相关的知识,希望对你有一定的参考价值。

技术分享

1.1 crond是什么

crondlinux系统中用来定期执行命令或指定程序任务的一种服务或软件。

特殊需求:(秒级别)crond服务就无法搞定了,一般工作中写脚本守护进程执行

crontab是用来管理用户的定时任务规则的

1.2 程序、进程及守护程序

程序文件:程序代码组成,但是没有执行。当前没执行。

进程所谓进程就是正在执行的程序

守护进程守护进程就是一直运行的程序

1.3 需要开机启动的项目:

network、sshd、rsyslog、crond、sysstat

使用

[[email protected] ~]# chkconfig --list |egrep -v "sshd|network|sysstat|rsyslog|crond"|awk ‘{print "chkconfig "$1" off"}‘

[[email protected] ~]# /etc/init.d/sshd status查看是否正在运行
openssh-daemon (pid  1112) is running...

1.4 为什么使用crond定时任务

linux系统的定时任务crond,相当于我们平时生活中的闹钟的功能。可以满足周期性执行任务的需求

1.5 不同系统下定时任务软件种类

linux系统下的定时任务软件还真不少例如:at,crontab,anacron。

at:适合仅执行一次就结束的调度任务命令。建议了解即可。

crontab:这个命令可以周期性的执行任务工作。要执行crontab这个命令,也需要启动一个服务crond才行,这个crontab是在生产工作中最常用的命令。

[[email protected] ~]# chkconfig --list crond

crond           0:off 1:off 2:on 3:on 4:on 5:on 6:off

anacron:这个命令主要用于非7*24小时开机的服务准备的它必不能指定具体时间执行任务工作而是以天为周期或者在系统每次开机后执行的任务工作了解即可

1.5.1 windows7系统的定时任务

开始→所有程序→附件→系统工具→选择任务计划程序

1.5.2 linux系统的定时任务

linux系统中定时任务调度的工作可以分为以下两个情况:

 ① linux系统自身定期执行的任务工作:系统周期性执行的任务工作,如轮询系统日志,备份系统数据,清理系统缓存等。

centos5.X例: [[email protected] log]# ll messages*

 -rw------- 1 root root 372258 Mar 14 20:48 messages

 -rw------- 1 root root 349535 Nov 11 18:13 messages.1

提示:centos 6.4日志轮询结尾是按时间了。

 centos6.X例: [[email protected] log]# ll messages*

-rw------- 1 root root  1591 3  25 21:57 messages

-rw------- 1 root root 78304 3   3 20:40 messages-20140303

-rw------- 1 root root 78050 3   8 19:42 messages-20140311

-rw------- 1 root root   745 3  18 00:46 messages-20140318

-rw------- 1 root root 77232 3  22 21:20 messages-20140325

   用户执行的任务工作:某个用户或系统管理员定期要做的任务工作,例如每隔5分钟和互联网上时间服务器进行时间同步,每天晚上0点备份站点数据及数据库数据,一般这些工作需要由每个用户自行设置才行。

 例: [[email protected] log]# crontab -l

 #time sync by lee at 2014-1-14

*/5 * * * * /usr/sbin/ntpdate  time.windows.com >/dev/null  2>&1

1.6 crontab指令说明

通过crontab我们可以在固定的间隔时间执行指定的系统指令或script脚本。时间间隔的单位是分钟,小时,日,月,周及以上的任意组合(注意:日和周不要组合)

1.6.1 使用者权限和定时任务文件

文件

说明

/etc/cron.deny

该文件中所列用户不允许使用crontab命令。

/etc/cron.allow

该文件中所列用户允许使用crontab命令,优先于/etc/cron.deny

/var/spool/cron

所有用户crontab配置文件默认都存放在此目录,文件名以用户名命名。

cat  /etc/crontab

 

ll  /var/spool/cron  查属性

cat  /var/spool/cron/root 查内容 相当于 crontab -l

1.6.2 参数

参数

含义

指定示例

-l(字母)

查看crontab文件内容

crontab -l

-e

编辑crontab文件内容

crontab -e

-i 

删除crontab文件内容,删除前会提示确认

crontab -ri

-r

删除crontab文件内容

crontab -r

-u user

指定使用的用户执行任务

crontab -u lee -l

提示:crontab{-l |-e}实际上就是在操作/var/spool/cron/当前用户这样的文件。

注:

crontab -e

/var/spool/cron/root

前者会检查语法,而后者不会。

visudo

/etc/sudoers

前者会检查语法,而后者不会。

1.6.3 指令的使用格式

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

crontab用户的定时任务一般分为6段(空格分隔,系统的定时任务则/etc/crontab分为7段),其中前五段位时间设定段,第六段为所要执行的命令或脚本任务段

 

1.6.4 crontab基本格式书写

1. crontab基本格式

* * * * * cmd

提示:

① cmd为要执行的命令或脚本,例如/bin/sh  /server/scripts/lee.sh.

② 每个段之间必须要有空格。

2. crontab语法格式中时间段的含义表

含义

取值范围

第一段

代表分钟

00-59

第二段

代表小时

00-23

第三段

代表日期

01-31

第四段

代表月份

01-12

第五段

代表星期

0-7(0和7都代表星期日)

3.  crontab语法格式中特殊符号的含义表

特殊符号

含义

*

*号表示任意时间都,就是“每”的意思,举例:如00 01 * * * cmd表示每月每周每日的凌晨1点执行cmd任务。

-

减号,表示分隔符,表示一个时间范围段,如17-19点,每小时的00分执行任务。00 17-19 * * * cmd。就是17,18,19点整点分别执行的意思。

逗号,表示分隔时间段的意思。30 17,18,19 * * * cmd 表示每天17,18,19点的半点执行cmd。也可以和“-”结合使用,如: 30 3-5,17-19 * * * cmd。

/n   

n代表数字,即”每隔n单位时间”,例如:每10分钟执行一次任务可以写 */10 * * * * cmd,其中 */10,*的范围是0-59,也可以写成0-59/10。

 

1.7 crond定时任务的七个基本要领

1 为定时任务规则加必要的注释

加了注释,就知道定时任务运行的是什么作业,以防以后作业混乱。这是个好习惯和规范。

[[email protected]~]# crontab -l

#time sync by lee at 2014-1-14

*/5 * * * * /usr/sbin/ntpdate  time.windows.com >/dev/null  2>&1

 

2 定时任务命令或程序最好写到脚本里

[[email protected] ~]# crontab -l

#backup www to /backup

00 00 * * * /bin/sh /server/scripts/www_bak.sh >/dev/null  2>&1

 

3 定时任务执行时要规范路径

#backup www to /backup

00 00 * * * /bin/sh /server/scripts/www_bak.sh >/dev/null  2>&1

 

4 执行shell脚本时前加/bin/sh

执行定时任务时,如果是执行脚本,尽量在脚本前面带上/bin/sh命名,否则有可能因为忘了为脚本设定执行权限,从而无法完成任务。

[[email protected] ~]# crontab -l

#backup www to /backup

00 00 * * * /bin/sh /server/scripts/www_bak.sh >/dev/null  2>&1

 

5 定时任务结尾加>/dev/null 2>&1

[[email protected] ~]# crontab -l

#backup www to /backup

00 00 * * * /bin/sh /server/scripts/www_bak.sh >/dev/null  2>&1

备注:1./dev/null为特殊的字符设备文件,表示黑洞设备或空设备。

2.>/dev/null 2>&1的作用

如果定时任务规范结尾不加 >/dev/null 2>&1,很容易导致硬盘inode空间被占满,从而系统服务不正常

strace -f passwd 追踪分析原因

centos  5  var/spool/clientmqueue邮件临时队列目录,垃圾文件存放于此,

如果是centos 6.4系统,默认不装sendmail服务,所以不会有这个目录。var/spool/postfix/maildrop/

postfix关闭   /etc/init.d/postfix stop    

关闭之后临时邮件目录被大量小文件填充

6 在指定用户下执行相关定时任务

这里要特别注意不同用户的环境变量问题,如果是调用了系统环境变量/etc/profile,最好在程序脚本中将用到的环境变量重新export下。

#!/bin/bash

export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/server/scripts:/oldb

oy/:/root/bin

/sbin/ifconfig eth0 >>/server/log/ip.txt 2>&1

echo $PATH   >>/server/log/ip.txt 2>&1

 

7 生产任务程序不要随意打印输出信息

在调试好脚本程序后,应尽量把DEBUG及命令输出的内容信息屏蔽掉,如果确实需要输出日志,可定向到日志文件里,避免产生系统垃圾。

8配置定时任务规范操作过程

①首先要在命令行操作成功,然后复制成功的命令到脚本里,在各个细小环境减少出错的机会。

②然后测试小本,测试成功后,复制脚本的规范路径到定时任务配置里,不要手敲。

③先在测试环境下测试,然后正式环境规范部署。

1.8 书写脚本规范步骤

  1. 尽量用脚本,但是要命令行测试好
  2. 复制命令到脚本里
  3. 脚本放到指定目录
  4. /bin/bash全路径测试脚本
  5. 复制命令行测试的脚本
  6. crontab -e
  7. crontab -l 检查定时任务

1.9 生产场景如何调试crond定时任务

规范的公司开发和运维人员操作流程:个人的开发配置环境-->办公室的测试环境-->idc机房的测试环境-->idc机房的正式环境。

  1. 增加执行频率调试任务

在调试时,把任务执行频率调快一点,看能不能正常执行,如果正常,那就没问题了,再改成需要的任务的执行时间。

注意:有些任务时不允许频繁执行的,例如:定时往数据库里插入数据,这样的任务要在测试机上测试好,然后正式线上出问题的机会就少了。

  1. 调整系统时间调试任务

用正确的执行任务的时间,设置完成后,可以修改下系统当前时间,改成任务执行时间的前几分钟来测试(或者重启定时任务服务)

  1. 通过日志输出调试定时任务

在脚本中加入日志输出,然后把输出打到指定的日志中,然后观察日志内容的结果,看是否正确执行。

或像下面的内容把脚本结果定向到一个log文件里重定向>即可,不需要加>>追加,这样日志就不会一直变大,如/app/log.log

[[email protected] scripts]# crontab -l|tail -2

#print date to file 20160910

#00 9,14 * * 6,0 /bin/sh /server/scripts/oldboy.sh >/app/log.log 2>&1

可也以在脚本里面echo 1 >/tmp/a.log

脚本中加输出

[[email protected] scripts]# cat tar.sh

#!/bin/bash

cd / &&\

tar zcvf /tmp/etc_$(date +%Y%m%d%H).tar.gz ./etc >/tmp.log 2>&1

 

  1. 注意一些任务命令带来的问题

注意: * * * * * echo “==”>>/tmp/lee.log >/dev/null 2>&1 这里隐藏的无法正确执行的任务配置,原因是前面多了>>,或者去掉结尾的 >/dev/null 2>&1。

  1. 注意环境变量导致的定时任务故障

crontab执行shell是智能识别为数不多的系统环境变量,一般用户定义的普通变量是无法识别的,如果在编写的脚本中需要使用这些变量,最好使用export重新声明下该变量,脚本才能正常执行,例如:生产情况和java相关的服务任务和脚本。

  1. 通过定时任务日志调试定时任务

[[email protected] ~]# tail -f /var/log/cron 

Mar 26 15:55:01 angelT CROND[3415]: (ida) CMD (/usr/sbin/ntpdate time.windows.com >/dev/null 2>&1)

Mar 26 15:55:01 angelT CROND[3416]: (root) CMD (/usr/sbin/ntpdate  time.windows.com >/dev/null  2>&1)

Mar 26 16:00:01 angelT CROND[3422]: (root) CMD (/usr/sbin/ntpdate  time.windows.com >/dev/null  2>&1)  

1.10 crontab定时任务生产应用问题总结箴言

1.10.1 系统环境变量问题

crontab执行shell是智能识别为数不多的系统环境变量,一般用户定义的普通变量是无法识别的,如果在编写的脚本中需要使用这些变量,最好使用export重新声明下该变量,脚本才能正常执行,例如:生产情况和java相关的服务任务和脚本。

范例

#!/bin/bash

export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/server/scripts:/oldb

oy/:/root/bin

/sbin/ifconfig eth0 >>/server/log/ip.txt 2>&1

echo $PATH   >>/server/log/ip.txt 2>&1

1.10.2 定时任务要用绝对路径

crontab执行shell时,如果shell路径是相对路径或shell例含有相对路径,此时就会找不到任务路径,因此在shell脚本中调用脚本或定时任务地哦啊用的脚本都要使用绝对路径。

范例:

* * * * * echo +>oldboy.log 这是相对路径的写法,不规范。会输出到/root/oldboy.log

系统的定时任务 /

用户的定时任务 在用户的家目录下

1.10.3 定时任务的脚本权限问题

要确保crontab的执行者有访问shell脚本所在的目录并且执行此shell脚本的权限(可用chmodchown修改脚本权限和所有者)。当然,最佳方法是执行脚本前加/bin/sh执行测试下。在配置任务执行脚本时,可以省略当前用户配置,但是最好带上/bin/sh,否则有可能因为忘了为脚本设定执行权限,而无法完成任务。

范例

* * * * * /server/scripts/tar.sh  ç此时如果tar.sh没有可执行权限就无法执行任务了

* * * * * /bin/sh /server/scripts/tar.sh

1.10.4 时间变量问题用反斜线

%”号在crontab任务配置中被认为是newline,需要要用“\”来转译。crontab任务命令中,若果有“date+%Y%m%d”,必须替换为:"date +\%Y\%m\%d",但写在脚本中就不需要转译了。这也是老师推荐使用脚本文件的原因之一,如果是脚本文件,那么“%”就不需要转译。

范例

#tar comment by Bison at20160910

* * * * * cd /etc/ && tar zcvf /tmp/service_$(date +\%Y\%m\%d\%H\%M).tar.gz ./services

脚本实现

* * * * * /bin/sh /server/scripts/tar.sh > /dev/null 2>&1

1.10.5 >/dev/null 2>&1问题 (1>/dev/null 2>/dev/null),(&>dev/null)

当定时任务在你所指定的时间执行后系统会寄一封信给你显示该程序执行的内容若系统未开启邮件服务就会导致邮件临时目录/var/spool/clientmqueue碎文件逐渐增多,以至于大量消耗inode数量,其实可在每一行任务结尾空一格后加上>/dev/null 2>&11>/dev/null 2>/dev/null将输出定向为空来规避这个问题

如果需要打印日志输出可也以追加到指定的日志文件里尽量不要留空如果任务本身是命令的话,添加>/dev/null 2>&1时要慎重,许多测试并且有检查手段。如:* * * * * echo "==" >> /tmp/oldboy.log >/dev/null 2>&1,该任务规则就是无法执行的

1.10.6 定时任务规则之前加注释

写定时任务规则时要加上注释这是个好习惯

范例

#tar comment by Bison at20160910

* * * * * /bin/sh /server/scripts/tar.sh > /dev/null 2>&1

1.10.7 使用脚本需代替命令行定时任务

使用脚本执行任务可以让我们少犯错误提升效率、规范是个好习惯。定时任务中执行命令有一些限制,如时间变量问题,多个重定向命令混用问题等。

范例

#tar comment by Bison at20160910

* * * * * /bin/sh /server/scripts/tar.sh > /dev/null 2>&1

1.10.8 避免不必要的程序及命令输出

在开发定时任务程序或较本市在调试好脚本程序后应尽量吧DEBUG及命令输出的内容信息屏蔽掉,如果还需要,可以定向到指定日志文件里,以免产生多余的系统垃圾。

平时喜欢tar zcvf。这个-v参数就是查看打包信息的,做成定时任务就不要输出了。

范例

* * * * * cd /etc/ && tar zcvf /tmp/service.tar.gz ./servicesç这里的v参数就是不必要的

* * * * * cd /etc/ && tar zcvf /tmp/service.tar.gz ./services >/tmp/tar.log

1.10.9 切到目标目录的上一级打包目标

例如打包/etc/services,执行

cd /etc/ && tar zcf /tmp/service.tar.gz ./services

如果想保留内容的目录结构可以从根开始打包

[[email protected] ~]# tar zcvf ifcfg-eth0.tar.gz /etc/sysconfig/network-scripts/ifcfg-eth0

tar:从成员名中删除开头的/

/etc/sysconfig/network-scripts/ifcfg-eth0

[[email protected] ~]# tar -tf ifcfg-eth0.tar/.gz

/etc/sysconfig/network-scripts/ifcfg-eth0

1.10.10 定时任务脚本中的程序命令尽量用全路径

第2章 练习作业题

① 每隔1分钟,打印一个"+"号到oldboy.log文件。

mkdir -p /server/scripts/

cd /server/scripts/

/bin/echo "+" >> /server/scripts/oldboy.log

cat oldboy.log

crontab -e

#print + to oldboy.log 20160910

* * * * * /bin/echo "+" >> /server/scripts/oldboy.log

tail -f /server/scripts/oldboy.log

② 每隔5分钟 将/etc/services文件打包备份到/tmp下,每次生成不同的备份包名。

[[email protected] etc]# /bin/tar zcvf /tmp/etc_$(date +%F_%H-%M).tar.gz ./services

./services

[[email protected] etc]# ls -l /tmp

total 168

-rw-r--r-- 1 root   root     127304 Sep 10 17:48 etc_2016-09-10_17-48.tar.gz

[[email protected] scripts]# touch backup_etc.sh

[[email protected] scripts]# vim backup_etc.sh

#!/bin/bash

cd /etc &&\

/bin/tar zcf /tmp/etc_$(date +%F_%H-%M).tar.gz ./services

~                                                                                                                                     

~

 "backup_etc.sh" 3L, 85C written

[[email protected] scripts]# cat backup_etc.sh

#!/bin/bash

cd /etc &&\

/bin/tar zcf /tmp/etc_$(date +%F_%H-%M).tar.gz ./services  

[[email protected] scripts]# /bin/sh backup_etc.sh

[[email protected] scripts]# crontab -e

 

#backup ete/services by Bison 20160910

*/5 * * * * /bin/sh /server/scripts/backup_etc.sh >/dev/null 2>&1

~                                                                                                                                     

~                                          

"/tmp/crontab.48FL0C" 11L, 379C written

crontab: installing new crontab

[[email protected] scripts]# crontab -l|tail -f

#backup ete/services by Bison 20160910

*/5 * * * * /bin/sh /server/scripts/backup_etc.sh >/dev/null 2>&1

                      

③ 每天晚上12点,打包站点目录/var/www/html/data目录下,每次生成不同的备份包名。

[[email protected] scripts]# mkdir /var/www/html -p

[[email protected] scripts]# cd /var/www

[[email protected] www]# tar zcf /data/www_$(date +%F).tar.gz ./html

[[email protected] data]# cd /server/scripts/

[[email protected] scripts]# touch backup_www.sh

[[email protected] scripts]# vim backup_www.sh

#!/bin/bash

cd /var/www/ &&\

tar zcf /data/www_$(date +%F).tar.gz ./html

~                                              

"backup_www.sh" 3L, 73C written                                                                                     

[[email protected] scripts]# /bin/sh backup_www.sh

[[email protected] scripts]# ll /data

total 20

-rw-r--r-- 1 root root  112 Sep 10 18:43 www_2016-09-10.tar.gz

[[email protected] scripts]# crontab -e

#backup www.html by Bison 20160910

00 00 * * * /bin/sh /server/scripts/backup_www.sh >/dev/null 2>&1

~                                                                                                                                     

~  

"/tmp/crontab.zOwU84" 14L, 481C written

crontab: installing new crontab                                            

④在每周6的凌晨3:15执行/home/shell/collect.pl,并将便准输出和标准错误输出到/dev.null设备,请写出crontab中的语句。

#x /home/shell/collect.pl by Bison 20160910

03 * * 6 /bin/sh /home/shell/collect.pl >/dev/null 2>&1

⑤crontab11月份内,每天的早上6点到12点钟,每隔2小时执行一次/usr/bin/httpd.sh怎么实现?

crontab -e

#x /usr/bin/httpd.sh by Bison 20160910

00 6-12/2 * 11 * /bin/sh /usr/bin/ht

以上是关于定时任务的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot的定时任务

SpringBoot的定时任务

SpringBoot的定时任务

spring实现动态定时任务

数据库定时执行sql mysql定时任务 event 执行定时任务 和sql server定时任务 作业执行定时任务

Linux设置定时任务