道者编程

crontab定时任务详解

crontab:Unix系统中用于设置用户任务周期性调度的命令,俗称定时任务

一:语法

crontab -e #设置定时任务,用法类似vi编辑器
crontab -l #列出当前的定时任务

更多用法参考手册

/var/spool/cron/ 目录存放用户设置的定时任务,每个任务以用户创建者名字命名。比如root用户设置的定时任务,那么对应的设置文件就是:/var/spool/cron/ root

二:设置定时

设置定时分为6个字段,前面5个字段分别是:分 时 日 月 周;最后一个字段是执行命令段;如:

* * * * * php a.php #表示一分钟执行一次a.php程序

                                              此图来源于互联网

特殊字符定义:

"*"代表所有的取值范围内的数字,如月份字段为*,则表示1到12个月;

"/"代表每一定时间间隔的意思,如分钟字段为*/10,表示每10分钟执行1次。

"-"代表从某个区间范围,是闭区间。如“2-5”表示“2,3,4,5”,小时字段中0-23/2表示在0~23点范围内每2个小时执行一次。

","分散的数字(不一定连续),如1,2,3,4,7,9。

三:实例:

* * * * * command  #每分钟执行
*/5 * * * * command  #5分钟执行
*/60 * * * *  #每小时执行,注意啊,* */1 * * * 网上很多这样写是错误的,实际会每分钟都执行
10,15 * * * *  command  #每小时的第10和15分钟执行
10,15 9-12 * * *  command  #每天上午9-12点的第10和15分钟执行command
30 22 * * * /usr/local/nginx/sbin/nginx -s reload #每天22:30分重启nginx
20 8 1,10,20 * * command #每月1号,10号,20号,8:20分执行
* 20-7/1 * * * command #20点到7点,每隔1小时执行
10 9 * * 6,0 command 每周六,周日 9:10分执行


crontab最小单位是分,如果按秒执行咋办?比如一个PHP程序以10秒执行一次,介绍两种方法:

(1):在crontab中加延时执行

* * * * * sleep 10; command 
* * * * * sleep 20; command 
* * * * * sleep 30; command 
* * * * * sleep 40; command 
* * * * * sleep 50; command 
 这里要写5个,如果是一秒执行一次,要写59个。

(2):编写shell脚本实现,脚本名称:t.sh

#!/bin/bash
file="/usr/local/www/t.php"
while :
    do
        fileCount=`ps -ef | grep "$file" | grep -v "grep" | wc -l`
        if [[ $fileCount < 1 ]]; then #判断php进程是否还在,如果不在拉起来
            nohup /usr/local/php/bin/php /usr/local/www/t.php > /dev/null 2>&1
        fi
        sleep 10 #延时10秒
    done
exit 0

 设置一分钟执行一次

* * * * * /usr/local/t.sh #每分钟执行
其实这个脚本就是个死循环,crontab每分钟触发一下脚本,不过这里会导致一个问题,如果脚本还在运行中,每分钟再触发一次,会导致系统有多个进程。

两种方式解决,1:把延时循环放在最终的脚本上,2,:加锁,这里就是t.php,在这个程序里延时。

#!/bin/bash
file="/usr/local/www/t.php"
fileCount=`ps -ef | grep "$file" | grep -v "grep" | wc -l`
	if [[ $fileCount < 1 ]]; then #判断php进程是否还在,如果不在拉起来
            nohup /usr/local/php/bin/php /usr/local/www/t.php > /dev/null 2>&1
        fi
exit 0
php中执行延时

<?php

for($i=1;$i<=60; $i++){
	sleep(10);
	echo date('h:i:s');
}

也可以再写一个shell脚本,crontab 隔一段时间执行一下该脚本,该脚本判断是否执行延时脚本。只要crontab执行的脚本中没有延时代码,一般不会出现多个进程。

我们在用加锁的方式搞一搞,这种方式更简单:flock

nohup flock -xn /usr/local/www/t.lock -c 'php /usr/local/www/t.php' > /dev/null 2>&1

 -x 表示对文件加上排他锁,-n 表示文件使用非阻塞模式,-c 选项指明加锁成功后要执行的命令。以上flock 命令的整体含义就是:如果对 /usr/local/www/t.lock 文件(如果文件不存在, flock 命令会自动创建)加锁成功就执行后面的php命令,否则不执行。这样就不会有多个进程跑

开启日志

sudo vi /etc/rsyslog.d/50-default.conf

cron.*              /var/log/cron.log #将cron前面的注释符去掉 

#重启rsyslog
sudo  service rsyslog  restart
如果修改了系统时间:

/etc/init.d/cron restart ( service cron restart )
 


最新评论:
我要评论:

看不清楚