两则预防crontab重复执行任务策略

6 篇文章 0 订阅

案例分析

前台异步上传文件到云端后台cron

*/10 * * * * /usr/local/bin/php /path/to/upload.php  >> /tmp/apkqueue.log

有时候上传一个文件到云端会很耗时,一个cron还没有跑完,下一个cron又开启了,并且一个文件可能被大于一个cron在同时上传。

如果一个脚本的执行时间 比cron的间隔大的多的话,系统就会同时存在多个相同脚本同时执行。再如果脚本的子任务没有加锁的话,那么会出现同一条数据

被多个cron执行,造成系统资源浪费。解决的办法就是加锁控制同一个脚本在系统中任何时刻只有一个进程执行,通过锁的粒度可以做到不同的控制。

以下是我知道的两种策略:

1,执行的脚本加锁

lockf,flock

例:

* * * * * /usr/bin/flock -xn /tmp/full_diff.lock -c 'cd /usr/local/www/admin; /usr/local/bin/php upload.php > /dev/null 2>&1'

30 * * * * (/usr/bin/lockf -s -t 0 /tmp/cdn.push.lock /usr/local/bin/php /path/to/upload.php >> /tmp/log 2>&1)

2,在脚本中加锁
<?php
$fp = fopen("/tmp/lock.txt", "w+");
if (flock($fp, LOCK_EX | LOCK_NB)) { // 进行排它型锁定
  	run(); //执行任务
	flock($fp, LOCK_UN); // 释放锁定
} else {
	echo "Couldn't lock the file !";
}
fclose($fp);
?>


2,对子任务加锁(如果有)

mysql的innodb update操作是行锁的,可以利用这点对子任务加锁,一条数据代表一个子任务

这样可以更西粒度的控制一个子任务同一时刻只有一个进程在执行,同时还可以开启多个进程。

function run($procid=0)//人为标识的进程id
{
	$procNum = 10;//假设开10个进程


	$data = select(..) from .. where id%$procNum=$procid;
	foreach($data as $row){
		exec($row);
	}



}


function exec($val)
  {
            //lock
            if(model()->lock($val['id'])) //执行一条update table set status='lock' where id=12312 and status='unlock';
                return;
		...run..
            model()->succ($val['id']);

    }


crontab


0 * * * * /proc id=0
1 * * * * /proc id=1
2 * * * * /proc id=2
...
9 * * * * /proc id=9

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值