一、总结
一句话总结:
现象:发现插入到数据库里的数据【有大量重复的数据】。(注释:用的 redis 驱动队列)
原因:发现是【因为任务的执行时间太长,导致任务过期,重新把任务放到队列里面】,然后问题就出来了,超时的任务并没有停止掉,而新放到队列里的任务也在执行,这就导致有两个队列在同时执行一个任务。
解释:【参数项 --timeout 的值应该始终小于配置项 retry_after 的值】,这是为了【确保队列进程总在【任务重试】以前关闭】。如果 --timeout 比 retry_after 大,那么你的任务可能被执行两次。
二、Laravel 队列重复执行同一个任务
在 laravel 中使用队列执行任务,任务的逻辑大体是循环插入数据 (这里我就要说一下了,循环里面最好不要执行插入/修改操作)。
这是大体代码:
$data=array(这是数据);
foreach ($data as $key => $value) {
//这里是判断数据是否已存在
//code....
$table1 = new Table1;
$table1->field1=$value['field1'];
$table1->field2=$value['field2'];
if($table1->save()){
$table2 = new Table2;
$table2->table1_id=$table1->id;
$table2->field1=$value['field3'];
$table2->field2=$value['field4'];
$table2->save();
}
}
但是发现插入到数据库里的数据有大量重复的数据。(注释:用的 redis 驱动队列)
查看队列执行日志,发现是因为任务的执行时间太长,导致任务过期,重新把任务放到队列里面,然后问题就出来了,超时的任务并没有停止掉,而新放到队列里的任务也在执行,这就导致有两个队列在同时执行一个任务。
我查看了文档发现,有这么一个东西:
注:参数项 --timeout 的值应该始终小于配置项 retry_after 的值,这是为了确保队列进程总在任务重试以前关闭。如果 --timeout 比 retry_after 大,那么你的任务可能被执行两次。
然后就去检查了参数设置,--timeout 为 500,而 retry_after 才 90,怪不得会重复执行