最近在使用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 没有起作用的话,很有可能坑点在这里。简要列出一个简要方案,其实知道了问题在哪,
对症下药也很简单。方案如下:
- 设置不同的队列名,不同的队列任务,建议设置不同的名称,键名不一致也比较清晰
- 建议设置过期时间稍长,针对业务需求来预估,稍大增加即可