当前位置:Gxlcms > 数据库问题 > Laravel5.2队列驱动expire参数设置带来的重复执行问题 数据库驱动

Laravel5.2队列驱动expire参数设置带来的重复执行问题 数据库驱动

时间:2021-07-01 10:21:17 帮助过:23人阅读

,一定要设置小于队列任务过期时间expire参数!

还有,Laravel5.2的queue:work并没有--timeout=60这个参数。。。。。


最后是队列执行完的处理逻辑。

如果队列执行成功会删除jobs的数据,这没什么问题。如果失败,包括超时、异常等,会根据设置的最大失败次数判断是否插入一条新数据,或者插入一条Failed数据到“failed_jobs”表。

出现错误时,handleJobException的异常处理调用DatabaseQueue.php的release方法,$job->release($delay),最终是pushToDatabase实现。

插入新数据时候,attempts是失败次数,reserved为0,available_at为当前时间戳加上超时配置时间,

这样整个队列处理就形成了完整的数据操作。


Laravel5.4对队列功能进行了很大的修改,手册中的提示

任务过期和超时

任务执行时间

在配置文件 config/queue.php 中,每个连接都定义了 retry_after 项。该配置项的目的是定义任务在执行以后多少秒后释放回队列。如果retry_after 设定的值为 90, 任务在运行 90 秒后还未完成,那么将被释放回队列而不是删除掉。毫无疑问,你需要把 retry_after 的值设定为任务执行时间的最大可能值。


Laravel5.4去掉了queue的listen命令,work也增加了超时参数。Laravel5.5出来的时候应该必须直接升级上去。


附录:Laravel5.2测试的脚本,之前网上搜出来的都比较早,还是把job写成命令的方式,其实5.2以后job使用非常简单。

jobs下定义job任务,handle可以增加一些测试方案,比如我这种抛出异常,直接Failed的

class MyJob extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;
    private $key;
    private $value;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($key, $value)
    {
        $this->key = $key;
        $this->value = $value;
    }
    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        for($i=0;$i<20;$i++){
            echo "$i\n";
            sleep(1);
        }
        echo "sss\t".$this->key."\t".date("Y-m-d H:i:s")."\n";
        throw new \Exception("测试\n");
//         Redis::hset(‘queue.test‘, $this->key, $this->value);
    }
    public function failed()
    {
        dump(‘failed‘);
    }
}

控制器访问设置任务队列,key和value之前用了测试redis插入的,可以按自己的测试方案设置job参数。

        for($i = 0; $i < 5; $i ++) {
            echo "$i";
            $job = (new MyJob($i, $i))->delay(20);
            $this->dispatch($job);
        }

我的例子设置了5个队列,开启多个shell并发执行artisan测试吧。


本来想将redis队列代码读完,一起发出来的,最近事情太多,redis代码也没怎么看。

redis驱动可以参考 http://www.cnblogs.com/z1298703836/p/5346728.html  这篇文章对Laravel队列redis驱动逻辑介绍的很详细了,redis驱动使用的list和zset结构储存队列,执行过程会移除转存队列,没有数据库的“for update” 操作,所以应该不是存在队列阻塞的情况。

BUT队列任务过期时间设置和数据库驱动是一样的,所以同样

queue:listen的执行时间参数 --timeout=60,一定要设置小于队列任务过期时间expire参数!


终于写完了。。。

Laravel5.2队列驱动expire参数设置带来的重复执行问题 数据库驱动

标签:laravel   php   队列   

人气教程排行