定时任务

一、crond简介:

crond是linux下用来周期性的执行某种任务和程序或等待处理某些事件的一个守护进程,相当于window下的计划任务。
crond进程每分钟会定期检查是否有要执行的任务,如果有,则会自动执行。

二、crond的安装包

[root@king ~]# rpm -qa cronie
cronie-1.4.4-16.el6_8.2.x86_64
[root@king ~]# rpm -ql cronie
/etc/cron.d
/etc/cron.d/0hourly
/etc/cron.deny
/etc/pam.d/crond
/etc/rc.d/init.d/crond
/etc/sysconfig/crond
/usr/bin/crontab
/usr/sbin/crond
/usr/share/doc/cronie-1.4.4
/usr/share/doc/cronie-1.4.4/AUTHORS
/usr/share/doc/cronie-1.4.4/COPYING
/usr/share/doc/cronie-1.4.4/ChangeLog
/usr/share/doc/cronie-1.4.4/INSTALL
/usr/share/doc/cronie-1.4.4/README
/usr/share/man/man1/crontab.1.gz
/usr/share/man/man5/crontab.5.gz
/usr/share/man/man8/cron.8.gz
/usr/share/man/man8/crond.8.gz
/var/spool/cron

三、crond配置文件说明

linux分为系统任务调度和用户任务调度

1、系统任务调度:系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。在/etc目录下有一个crontab文件,这个就是系统任务调度的配置文件。
配置文件说明
[root@king ~]# cat /etc/crontab 
SHELL=/bin/bash#<=====系统使用的shell
PATH=/sbin:/bin:/usr/sbin:/usr/bin#<=====系统执行命令的路径
MAILTO=root#<=====给那个用户发邮件,如果为空,则表示不给用户发送任务的执行信息
HOME=/#<=====执行命令或脚本时的目录

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)#<=====分钟(0-59)
# |  .------------- hour (0 - 23)#<=====小时(24制,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
                用户名      执行的命令
使用者权限文件:
文件:
/etc/cron.hourly/
说明:
系统定时任务每个小时运行这个目录里的内容

文件:
/etc/cron.daily/
说明:
系统定时任务每天运行这个目录里的内容

文件:
/etc/cron.monthly/
说明:
系统定时任务每月运行这个目录里的内容

文件:
/etc/cron.weekly/
说明:
系统定时任务每周运行这个目录里的内容

文件:
/etc/cron.deny
说明:
该文件中所列用户不允许使用crontab命令

文件:
/etc/cron.allow
说明:
该文件中所列用户允许使用crontab命令

文件:
/var/spool/cron/
说明:
所有用户crontab文件存放的目录,以用户名命名

系统定时任务+logrotate命令 完成对 日志的日志切割/日志轮询
/var/log/cron
/var/log/messages
/var/log/secure

2、用户任务调度:用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用 crontab 工具来定制自己的计划任务。所有用户定义的crontab 文件都被保存在 /var/spool/cron目录中。其文件名与用户名一致
配置方法为:crondtab -e

四、crontab格式说明

crontab文件的含义:
用户所建立的crontab文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式如下:
minute hour day month week command
其中:
minute: 表示分钟,可以是从0到59之间的任何整数。
hour:表示小时,可以是从0到23之间的任何整数。
day:表示日期,可以是从1到31之间的任何整数。
month:表示月份,可以是从1到12之间的任何整数。
week:表示星期几,可以是从0到7之间的任何整数,这里的0或7代表星期日。
command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。

在以上各个字段中,还可以使用以下特殊字符:
星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。

五、crond的服务及命令

1、crond的服务
安装crontab:
yum install crontabs
服务操作说明:
/sbin/service crond start //启动服务
/sbin/service crond stop //关闭服务
/sbin/service crond restart //重启服务
/sbin/service crond reload //重新载入配置
/sbin/service crond status //启动服务

加入开机自动启动:
chkconfig  crond on

2、crontab命令详解
1.命令格式:
crontab [-u user] file
crontab [-u user] [ -e | -l | -r ]
2.命令功能:
通过crontab 命令,我们可以在固定的间隔时间执行指定的系统指令或 shell script脚本。时间间隔的单位可以是分钟、小时、日、月、周及以上的任意组合。这个命令非常设合周期性的日志分析或数据备份等工作。
3.命令参数:
-u user:用来设定某个用户的crontab服务
-e:编辑某个用户的crontab文件内容。如果不指定用户,则表示编辑当前用户的crontab文件。
-l:显示某个用户的crontab文件内容,如果不指定用户,则表示显示当前用户的crontab文件内容。
-r:从/var/spool/cron目录中删除某个用户的crontab文件,如果不指定用户,则默认删除当前用户的crontab文件。
-i:在删除用户的crontab文件时给确认提示。

六、时间配置练习

使用实例
实例1:每1分钟执行一次command
命令:
* * * * * command
实例2:每小时的第3和第15分钟执行
命令:
3,15 * * * * command
实例3:在上午8点到11点的第3和第15分钟执行
命令:
3,15 8-11 * * * command
实例4:每隔两天的上午8点到11点的第3和第15分钟执行
命令:
3,15 8-11 */2 * * command
实例5:每个星期一的上午8点到11点的第3和第15分钟执行
命令:
3,15 8-11 * * 1 command
实例6:每晚的21:30重启smb 
命令:
30 21 * * * /etc/init.d/smb restart

实例7:每月1、10、22日的4 : 45重启smb 
命令:
45 4 1,10,22 * * /etc/init.d/smb restart

实例8:每周六、周日的1 : 10重启smb
命令:
10 1 * * 6,0 /etc/init.d/smb restart

实例9:每天18 : 00至23 : 00之间每隔30分钟重启smb 
命令:
0,30 18-23 * * * /etc/init.d/smb restart

实例10:每星期六的晚上11 : 00 pm重启smb 
命令:
0 23 * * 6 /etc/init.d/smb restart

实例11:每一小时重启smb 
命令:
* */1 * * * /etc/init.d/smb restart

实例12:晚上11点到早上7点之间,每隔一小时重启smb 
命令:
* 230-7/1 * * * /etc/init.d/smb restart
实例13:每月的4号与每周一到周三的11点重启smb 
命令:
0 11 4 * mon-wed /etc/init.d/smb restart
实例14:一月一号的4点重启smb 
命令:
0 4 1 1 * /etc/init.d/smb restart

实例15:每小时执行/etc/cron.hourly目录内的脚本
命令:
* */1 * * * root run-parts /etc/cron.hourly

六、定时任务的配置案列

每5分钟同步下系统时间(时间服务器地址ntp1.aliyun.com)

1、在linux系统下运行命令或脚本,并确保命令或脚本无错误:
[root@king ~]# ntpdate ntp1.aliyun.com
 7 Mar 13:09:25 ntpdate[26112]: step time server 120.25.115.20 offset -28746.630159 sec

2、写入定时任务
[root@king ~]# crontab -e
[root@king ~]# crontab -l
*/5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com
3、检查---看日志是否正常运行
[root@king ~]# tail -f /var/log/cron 

Mar  7 13:13:01 king CROND[26125]: (root) CMD (ntpdate ntp1.aliyun.com)

4、检查结果是否正确
[root@king ~]# date -s "-100day"
Tue Nov 27 13:15:03 CST 2018
[root@king ~]# date +%F
2018-11-27
1分钟后查看时间,时间自动同步完成
[root@king ~]# date +%F
2019-03-07

每分钟把king添加进/tmp/ywx.txt文件
1、测试命令无误:
[root@king ~]# echo "king" >> /tmp/ywx.txt
[root@king ~]# cat /tmp/ywx.txt 
king

2、配置定时任务
[root@king ~]# crontab -e
[root@king ~]# crontab -l
* * * * * /bin/echo "king" >> /tmp/ywx.txt
3、检查日志,查看定时任务是否执行
[root@king ~]# tail -f /var/log/cron
Mar  7 13:30:01 king CROND[26376]: (root) CMD (/bin/echo "king" >> /tmp/ywx.txt)
4、查看结果
[root@king ~]# cat /tmp/ywx.txt 
king
king

七、配置crontab中出现的故障及故障解决方法

1、特殊符号需要转义及使用"\":
每分钟显示一次系统时间
[root@king ~]# crontab -l
* * * * * date +%F >> /tmp/time.log
查看/var/log/cron日志
[root@king ~]# tail -f /var/log/cron
Mar  7 13:55:01 king CROND[26508]: (root) CMD (date +)
[root@king ~]# cat /tmp/time.log#<=====无信息记录

解决方法:
说明%在定时任务中有特殊的含义,需要转义
[root@king ~]# crontab -l
* * * * * date +\%F >> /tmp/time.log
查看/var/log/cron日志
[root@king ~]# tail -f /var/log/cron
Mar  7 13:57:01 king CROND[26525]: (root) CMD (date +%F >> /tmp/time.log)
[root@king ~]# cat /tmp/time.log#<=====信息记录正常
[root@king ~]# cat /tmp/time.log 
2019-03-07

2、定时任务中命令或脚本的结果(正确或错误的结果)要定向到/dev/null或追加到文件中
(1)定时任务规则结尾不加>/dev/null 2>&1或者追加到文件中>>/tmp/king.txt 2>&1,很容易导致inode被使用尽,从而使服务不正常
   a、邮件软件开启,定时任务会不断给配置crontab的用户发送
     #you have new mail in /var/spool/mail/user(配置crontab的用户)
   b、关闭邮件软件
      [root@king ~]# /etc/init.d/postfix stop
        Shutting down postfix:                                     [  OK  ]
      [root@king ~]# chkconfig postfix off
   大量小文件堆积在/var/spool/postfix/maildrop/ ---inode满了
   
   模拟环境:
   在crontab中创建10000个任务  
   * * * * * /usr/sbin/ntpdate ntp1.aliyun.com
   
   1分钟后查看/var/spool/postfix/maildrop/
[root@king ~]# ll /var/spool/postfix/maildrop/ 
total 5772
-rwxr--r-- 1 root postdrop 502 Mar  7 14:12 00DA381FBB
-rwxr--r-- 1 root postdrop 494 Mar  7 14:12 00FD281DDD
-rwxr--r-- 1 root postdrop 494 Mar  7 14:12 011F781FD2
-rwxr--r-- 1 root postdrop 494 Mar  7 14:12 0189681FD3
-rwxr--r-- 1 root postdrop 494 Mar  7 14:12 02600801D4
-rwxr--r-- 1 root postdrop 495 Mar  7 14:12 0315A801BD
-rwxr--r-- 1 root postdrop 496 Mar  7 14:12 0352681F5E
-rwxr--r-- 1 root postdrop 496 Mar  7 14:12 0364281F5F
-rwxr--r-- 1 root postdrop 496 Mar  7 14:12 0376F81F60
......省略
   
   解决方法:
   1、定时任务规则结尾添加>/dev/null 2>&1或者追加到文件中>>/tmp/king.txt 2>&1
   
   2、删除大量小文件的方法
   a、创建大量的小文件:
      [root@king test]# echo {1..10000}.txt |xargs touch

   b、删除大量小文件
      [root@king test]# ls *.txt|xargs rm
   c、直接删除有大量小文件的目录(删除前请记录目录的属主、属组及权限属性),然后重新创建该目录并还原目录的属主、属组及权限属性
   
   
   
3、定时任务运行脚本的时候只能识别PATH下的/usr/bin和/bin,其它PATH的路径无法识别
   每分钟显示一次ip地址并追加到/tmp/ip.log
   [root@king ~]# which ifconfig
       /sbin/ifconfig
   [root@king ~]# crontab -l
    * * * * * ifconfig eth0 | awk -F "[ :]+" 'NR==2 {print $4}' >> /tmp/ip.log
     [root@king ~]# tail -f /var/log/cron
    Mar  7 22:42:01 king CROND[1832]: (root) CMD (ifconfig eth0 | awk -F "[ :]+" 'NR==2 {print $4}' >> /tmp/ip.log)

    [root@king ~]# cat /tmp/ip.log 
    [root@king ~]# 
    
   一直没有结果输出,原因为命令的环境变量:
   crontab默认的环境变量为/usr/bin和/bin
   
   解决方法:
   1、使用命令全路径
   2、使用脚本命令(推荐2条命令以上的使用脚本),并用/bin/sh 脚本来执行(避免了,没有赋予脚本x权限的问题)。在脚本的开头配置: 
     export /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:~/bin
    
   [root@king ~]# tail -f /var/log/cron 
    Mar  7 22:56:01 king CROND[1935]: (root) CMD (/sbin/ifconfig eth0 | awk -F "[ :]+"  'NR==2 {print $4}' >> /tmp/ip.log)
    
    [root@king ~]# tail -f /tmp/ip.log 
     202.1.1.105
     202.1.1.105
     
     输出正常!!!
     
    

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

[root@king ~]# tar zcvf /tmp/etc.tar.gz /etc
tar: Removing leading `/' from member names#<=====不必要的输出

解决方法:
使用相对路径
如:[root@king /]# cd / && tar zcf /tmp/etc.tar.gz etc

九、使用脚本来配置crontab模板方式

实例:
1、每分钟显示一次当前的系统时间并追加到/tmp/king.txt
2、每分钟将oldboy追加到/tmp/king.txt

脚本模板:

1、vim king.sh
==================模板====================================================================
#!/bin/bash

#systom time and oldboy to /tmp/king.txt every one min ywx 2019-3-7

export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:~/bin

/bin/date +\%F >> /tmp/log.txt

/bin/echo "oldboy" >> /tmp/log.txt
=======================================================================================
2、测试脚本
[root@king tmp]# sh king.sh 
[root@king tmp]# cat /tmp/log.txt 
2019-03-07
oldboy
3、写入crontab
[root@king tmp]# crontab -l
* * * * * /bin/sh /tmp/king.sh
4、查看结果

[root@king ~]# tail -f /var/log/cron 
Mar  7 23:14:01 king CROND[2000]: (root) CMD (/bin/sh /tmp/king.sh)
[root@king tmp]# cat /tmp/log.txt 
2019-03-07
oldboy
2019-03-07
oldboy

十、crontab的企业案例

linux定时任务生产java服务无法执行问题群友案例
老男孩oldboy关注20人评论14095人阅读2014-08-18 12:21:04

linux定时任务crond export变量问题群友案例

来自网友兄弟 北京@Grady(254553457) 的总结。

1)我写了一个重启resin的脚本,由于业务原因,需要定时在某一个时间重启下resin服务器,于是就在
crontab里配置了如下内容:
50 17 * * 1-5 root /usr/local/bin/resin_restart.sh
其中,resin_restart.sh内容如下:
#!/bin/sh
/usr/local/bin/xxresin_stop.sh
/usr/local/bin/xxresin_start.sh

2)有问题的时刻到来了,服务器虽然定时起来了,但是却报了如下错误:
Resin can't load com.sun.tools.javac.Main.  Usually this means that the JDK tools.jar is missing from the classpath, 
possibly because of using a JRE instead of the JDK.  
You can either add tools.jar to the classpath or change the compiler to an external one with <java compiler='javac'/> or jikes.
但是,明明已经在profile里配置了环境变量,为啥还找不到呢。折腾了需求没有搞定。

3)后来在QQ交流群114580181,找到了热心下老男孩老师,并请教,得到的回答是:
由于export变量问题导致:具体为,crontab执行shell时只能识别为数不多的系统环境变量,
普通环境变量一般是无法识别的,如果在编写的脚本中需要使用变量,最好使用export重新声明下该变量,
以确保脚本正确执行。以后作为一个开发基本规范写上。
------------------------
4)然后我在resin重启脚本里重新定义了下环境变量,脚本如下:
#!/bin/sh
#下面就是环境变量定义
JAVA_HOME="/opt/jdk1.6.0_18"
CLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
PATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:/opt/nginx-0.7.61/sbin:/opt/jdk1.6.0_18/bin:/opt/resin-3.0.25/bin:$PATH
export JAVA_HOME PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC CLASSPATH
/usr/local/bin/xxresin_stop.sh
/usr/local/bin/xxresin_start.sh

5)经过测试,定时任务此时顺利重启,在这里非常感谢老男孩老师给与的支持。

No space left on device常见企业故障案例1.故障描述及说明
某年某月某日某时,某人在工作中设置定时任务规则保存时,提示“No space left on device”,此时用df-h检查磁盘,发现还有剩余空间,再用df-i检查则显示inode已被100%占用了,也就是说inode数量耗尽了,导致系统无法在/var目录下创建文件,因为定时任务的配置在/var/spool/cron下,在ext3、ext4文件系统中,每个文件至少要占一个inode(前文已讲,不再赘述)。
最后,经过检查发现在/var/spool/clientmqueue/下有很多小文件,执行ls/var/spool/clientmqueue命令查看,很长时间都没能显示出结果,执行cd/var/spool/clientmqueue;rm-f*命令则会自动跳出来,无法实现删除。最后的解决方法是使用命令cd/var/spool/clientmqueue&&ls|xargs rm-f进行清理。
在清理时,如果文件数特别多,执行ls|xargs rm-f命令也会长时间无反应,不过,不要着急,命令正在处理中。当然,我们也可以使用更快的删除方法,如直接使用cd/var/spool&&rm-fr clientmqueue删除上级目录,然后执行如下命令:
mkdir clientmqueue && chmod 770 clientmqueue && chown smmsp.smmsp -R /var/spool/clientmqueue
修改回/var/spool/clientmqueue目录在系统中的原来默认权限:
[root@admin-3-3 ~]# ls -ld /var/spool/clientmqueue/
drwxrwx—— 2 smmsp smmsp 4096 12-12 1346 /var/spool/clientmqueue/2.故障原因分析
当系统中Crond定时任务执行的程序有输出内容时,输出内容会以邮件形式发给执行任务的用户(默认是root),而sendmail、postfix等mail服务没有启动时,这些输出内容就会在邮件队列临时目录中产生大量很小的文件,导致消耗大量的inode和block数量(在ext文件系统中,默认情况下格式化block的数量会远大于inode的数量),一旦inode数量耗尽,就会导致系统无法写入文件而报上述错误“No space left on device”。提示:上述为CentOS5系统中的故障案例,同样适合CentOS6,只是小文件多的路径为postfix的临时邮件队列目录了。
3.预防方法
1)尽量将Cron任务里面的命令或脚本中的命令结尾加上>/dev/null 2>&1,或在写定时执行脚本时,把输出定向到指定文件中(适合所有的情况)。
2)当然也可以开启邮件服务,不过最好不做,因为邮件服务会带来额外的安全问题。
3)加定时清理任务,比如,将find/var/spool/clientmqueue/-type f-mtime+30|xargs rm-f放入定时任务,每周处理一次(CentOS5适合),如果是CentOS6,则处理的路径为/var/spool/postfix/maildrop/。

十一、自己使用nginx模拟环境变量的案例

一、环境搭建:
1wget http://nginx.org/download/nginx-1.14.2.tar.gz下载nginx到/tmp
2、使用源码来安装nginx
3、启动nginx
[root@king sbin]# ps -ef | grep nginx
root       7129      1  0 23:27 ?        00:00:00 nginx: master process ./nginx

二、使用脚本的来实现每分钟重启nginx服务
脚本内容如下:/tmp/nginx.sh
=======================脚本内容===============
#!/bin/bash
#reboot nginx service  every 1 min by ywx 2019-3-7

/usr/local/nginx/sbin/./nginx -s stop >> /dev/null 2>&1
/usr/local/nginx/sbin/./nginx  >> /dev/null 2>&1
==============================================

三、写入定时任务
[root@king tmp]# crontab -l
* * * * * /bin/sh /tmp/nginx.sh
四、查看日志及结果
[root@king ~]# tail -f /var/log/cron 
Mar  7 23:41:01 king CROND[7228]: (root) CMD (/bin/sh /tmp/nginx.sh)
Mar  7 23:42:01 king CROND[7236]: (root) CMD (/bin/sh /tmp/nginx.sh)
Mar  7 23:43:01 king CROND[7259]: (root) CMD (/bin/sh /tmp/nginx.sh)
[root@king tmp]# tail -f /tmp/nginx.txt 
无结果

[root@king sbin]# ps -ef | grep nginx
root       7129      1  0 23:27 ?        00:00:00 nginx: master process ./nginx
www        7160   7129  0 23:31 ?        00:00:00 nginx: worker process
root       7263   1750  0 23:43 pts/1    00:00:00 tail -f /tmp/nginx.txt
root       7276   7242  0 23:44 pts/2    00:00:00 grep --color=auto nginx
nginx的进程id无变化

在脚本中添加环境变量:
NGINX="/usr/local/nginx/sbin"
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:$NGINX

脚本内容如下:/tmp/nginx.sh
=======================脚本内容===============
#!/bin/bash
#reboot nginx service  every 1 min by ywx 2019-3-7
NGINX="/usr/local/nginx/sbin"
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:$NGINX
/usr/local/nginx/sbin/./nginx -s stop >> /dev/null 2>&1
/usr/local/nginx/sbin/./nginx  >> /dev/null 2>&1
==============================================
[root@king tmp]# tail -f /var/log/cron
Mar  7 23:59:01 king CROND[7399]: (root) CMD (/bin/sh /tmp/nginx.sh)
观察nginx的进程id
[root@king sbin]# ps -ef | grep nginx
root       7380      1  0 23:56 ?        00:00:00 nginx: master process 


1分钟后nginx的进程id
[root@king sbin]# ps -ef | grep nginx
root       7388      1  0 23:57 ?        00:00:00 nginx: master process 

进程id号改变

十二、小结

 
      1、执行命令的结果不需要保存: >/dev/null 2>&1
      2、执行命令的结果需要的保存: >>/目录/文件 2>&1
      3、关闭邮件软件
      4、定时任务运行脚本的时候可以识别的PATH只有 /usr/bin和/bin,脚本命令要写全路径
      5、避免不必要的程序及命令输出
      6、打包压缩使用相对路径(切到目标目录的上一级打包目标)
      
      
定时任务书写操作步骤:
1)先在命令行调试成功。
2)再将命令复制到定时任务配置里。
3)然后保存,并使用tail-f测试观察结果。
4)如果遇到问题,可根据输出以及定时任务日志/var/log/cron文件内容排错。

posted @ 2020-09-27 15:03  yaowx  阅读(327)  评论(0编辑  收藏  举报