php

laravel中队列使用redis时的expire配置坑

最近在使用laravel中的队列系统,在使用redis队列过程中发现一个坑点,多任务投递队列系统后,在未消费的情况下,任务丢失,在寻找问题之后确定问题所在点;
首先可以在config/queue.php中配置laravel的队列属性,如下面所示:

'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue'  => 'default',
            'expire' => 60,
        ],

而在源码Illuminate\Queue\RedisQueue(此为命名空间)此类中看到其构造函数如下:

    /**
     * Create a new Redis queue instance.
     *
     * @param  \Illuminate\Redis\Database  $redis
     * @param  string  $default
     * @param  string  $connection
     * @param  int  $expire
     * @return void
     */
    public function __construct(Database $redis, $default = 'default',
                                $connection = null, $expire = 60)
    {
        $this->redis = $redis;
        $this->expire = $expire;
        $this->default = $default;
        $this->connection = $connection;
    }

由上述构造函数可以看出默认的过期时间便是60秒,这确实坑爹,怎么个坑爹法,这么说吧,如果短时间内投递多任务的话,上一个任务失败加上重试的时间超过60秒,后续的任务都还没享受到被执行的乐趣就胎死腹中,多坑爹。再看看队列中的push调用吧,简要了解下。

    /**
     * Push a new job onto the queue.
     *
     * @param  string  $job
     * @param  mixed   $data
     * @param  string  $queue
     * @return mixed
     */
    public function push($job, $data = '', $queue = null)
    {
        return $this->pushRaw($this->createPayload($job, $data), $queue);
    }

    /**
     * Push a raw payload onto the queue.
     *
     * @param  string  $payload
     * @param  string  $queue
     * @param  array   $options
     * @return mixed
     */
    public function pushRaw($payload, $queue = null, array $options = [])
    {
        $this->getConnection()->rpush($this->getQueue($queue), $payload);

        return Arr::get(json_decode($payload, true), 'id');
    }

其实也就是简要的调用了redis的队列应用,比较简单,易懂,所以如果laravel中的queue delay 没有起作用的话,很有可能坑点在这里。简要列出一个简要方案,其实知道了问题在哪,
对症下药也很简单。方案如下:

  • 设置不同的队列名,不同的队列任务,建议设置不同的名称,键名不一致也比较清晰
  • 建议设置过期时间稍长,针对业务需求来预估,稍大增加即可

Leave a Reply

Your email address will not be published.

twenty − 1 =