Laravel 队列重复执行同一个任务

一、总结

一句话总结:

现象:发现插入到数据库里的数据【有大量重复的数据】。(注释:用的 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,怪不得会重复执行