2021/03/30

Laravel任务调度异常中断,withoutOverlapping设置无法再执行


使用laravel任务调度功能,在 /etc/crontab 中设置每分钟执行任务调度程序

* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1

假如我们程序执行过长,超过1分钟,那么在下一次任务调度过来时,就会有出现重复执行的情况,所以我们通过会在代码处加入 withoutOverlapping 方法,这样如果在本地任务未执行完毕时,那么下一次任务调度过来就会跳过不再执行此任务。

$schedule->command('emails:send')->withoutOverlapping();

他的原理就是在第一次执行时写入互斥Mutex标记到缓存中,执行完毕后删除Mutex。这样如果重复任务进来发现Mutex存在就不会再执行。Mutex标记存放的地方取决于.env 配置的 CACHE_DRIVER 字段。

如果是 file,则Mutex存放在 storage/framework/cache 中。

如果是 redis,则Mutex存放在key *framework/schedule*

但是有时一些异常服务器关机,异常程序kill,导致任务中断,没有删除掉Mutex,那么后续我们再次启动任务调度时,发现此任务将一直没有执行。在这种情况下,手动将Mutex标记删除掉即可恢复正常。