Crontab里解决脚本时间重叠的问题

正文

Linux里的Crontab是一个好东西,但是它的默认最小执行频率是1分钟,但是我们在实际生产环境里有的时候遇到的脚本执行时间是大于1分钟的,这样就会出现一个很尴尬的情况,就是在1分钟过后,系统进程会出现多个脚本,neck and neck式的在后台运行,比如这样:
akb48

从上面的图可以看到,10点36分log499.sh没有执行完毕,10点37又开始了执行了一个新的log499.sh脚本。这种脚本冲突肯定不是我们所希望的,那么如何才能保证后台只是在一段时间里只执行一个脚本呢?

这个时候我们就要使用文件锁,flock,这种方法要比判断pid高大上的多。

首先假设我们的脚本名字叫abc.sh,这个脚本文件的执行时间是要大于1分钟的,同时我们再设定一个锁文件,位置就叫/tmp/abc.lock,这个文件可以是空的,然后crontab -e,添加一句命令如下:

1
* * * * * flock -xn /tmp/abc.lock -c 'sh /路径/abc.sh >> /记录日志的路径 2>&1'

这个时候静候crontab启动abc.sh,通过ps -ef|grep abc,发现在后台始终只有一个abc进程。

但是有的时候会有这样的一个问题,就是abc执行一次之后,在下一次该执行的时候却没有执行,好像crontab失效了一样,对于这样的情况,就需要添加下面的语句到abc.sh末尾:

1
2
3
rm -rf /tmp/abc.lock      #删除掉原有的锁文件
sleep n #睡n秒
touch /tmp/abc.lock #再新建一个锁文件

这样不断地更新lock锁文件,就会保证crontab每次都会按期执行。

这里要注意一下,里面我加了一句sleep n,这里的n是为了跨分钟的存在,这是为了防止没有走到下一个分钟又会生成一个新的lock锁文件,这样还是会出现重复启动脚本的情况。

这里就涉及到flock的一个原理:在每一次执行任务的时候都会先去尝试取到锁文件,如果取到了锁文件,那么就会下一步,反之就会放弃执行。A任务在运行的时候已经占据了lock文件,那么B任务来了,发现没有lock了,就不会执行任务。

这里我们使用了flock的三个参数:

1
2
3
-x, --exclusive: 获得一个独占锁
-n, --nonblock: 如果没有立即获得锁,直接失败而不是等待
-c, --command: 在shell中运行一个单独的命令

当然,flock还是有很多丰富的参数可以供各位使用,大家就各自去google一下吧。

参考资料

http://blog.csdn.net/fdipzone/article/details/38284009
http://chuansong.me/n/285635151949
https://segmentfault.com/q/1010000008039907

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------