Laravel队列执行使用频率限制
2020-08-22 本文已影响0人
众神开挂
框架从5.8升级到6.0,结果好多队列执行失败了,原因很简单
App\Jobs\XXXXX has been attempted too many times or run too long. The job may have previously timed out.
先贴出原来的代码
//设置任务执行的最大时间
public $timeout = 120;
/**
* 通过Redis限制队列任务
*
* @return void
*/
public function handle()
{
Redis::throttle('key')->block(0)->allow(1)->every(5)->then(function () {
info('Lock obtained...');
// 处理队列...
}, function () {
// 无法获取锁…
return $this->release(5);
});
}
使用了频率限制,队列会反复重新尝试执行,而且
注意:将受限制的作业释放回队列,仍然会增加工作的总数
attempts
。
这就导致重试次数过多导致任务失败,你需要放开次数限制,5.8是默认没有次数上限的,但在6.0的文档中多了这样的一段:
基于时间的尝试
作为另外一个选择来定义任务在失败前会尝试多少次,你可以定义一个任务超时时间。这样的话,在给定的时间范围内,任务可以无限次尝试。要定义一个任务的超时时间,在你的任务类中新增一个
retryUntil
方法:/** * 定义任务超时时间 * * @return \DateTime */ public function retryUntil() { return now()->addSeconds(5); }
这样的话就可以按照实际的需求设定任务的有效的执行时间,我把时间设置为:一天+
return now()->addSeconds(87000);
队列可以正常执行了,很好!
20200831补充,队列报错 ,RedisException(code: 0) 错误解决,异常提示如下:
[2020-08-28 15:26:10] test.ERROR: read error on connection to 127.0.0.1:6379 {"exception":"[object] (RedisException(code: 0): read error on connection to 127.0.0.1:6379 at H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Redis\\Connections\\Connection.php:111)
[stacktrace]
#0 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Redis\\Connections\\Connection.php(111): Redis->blPop(Array, 90)
#1 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Redis\\Connections\\PhpRedisConnection.php(168): Illuminate\\Redis\\Connections\\Connection->command('blpop', Array)
#2 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\RedisQueue.php(233): Illuminate\\Redis\\Connections\\PhpRedisConnection->blpop(Array, 90)
#3 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\RedisQueue.php(169): Illuminate\\Queue\\RedisQueue->retrieveNextJob('queues:send_mai...')
#4 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Worker.php(264): Illuminate\\Queue\\RedisQueue->pop('XXX')
#5 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Worker.php(118): Illuminate\\Queue\\Worker->getNextJob(Object(Illuminate\\Queue\\RedisQueue), 'XXX')
#6 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Console\\WorkCommand.php(112): Illuminate\\Queue\\Worker->daemon('redis', 'XXX', Object(Illuminate\\Queue\\WorkerOptions))
#7 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Console\\WorkCommand.php(96): Illuminate\\Queue\\Console\\WorkCommand->runWorker('redis', 'XXXX')
#8 [internal function]: Illuminate\\Queue\\Console\\WorkCommand->handle()
#9 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(32): call_user_func_array(Array, Array)
#10 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(90): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#11 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(34): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#12 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php(591): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#13 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Command.php(192): Illuminate\\Container\\Container->call(Array)
#14 H:\\Code\\kol\\vendor\\symfony\\console\\Command\\Command.php(255): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#15 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Command.php(179): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#16 H:\\Code\\kol\\vendor\\symfony\\console\\Application.php(1000): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#17 H:\\Code\\kol\\vendor\\symfony\\console\\Application.php(271): Symfony\\Component\\Console\\Application->doRunCommand(Object(Illuminate\\Queue\\Console\\WorkCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#18 H:\\Code\\kol\\vendor\\symfony\\console\\Application.php(147): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#19 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Application.php(90): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 H:\\Code\\kol\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Console\\Kernel.php(131): Illuminate\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#21 H:\\Code\\kol\\artisan(37): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#22 {main}
"}
解决方法:
- 查看config->redis中的配置文件,设置read_time_out=0,或者不做设置
// 发送邮件队列
'queue' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' =>env('REDIS_QUEUE_DB', 3),
]
- 修改redis配置中的过期时间 timeout 是否是0,0为永不过期
- 修改php配置文件 ,延长 default_socket_timeout 时间 ,这里我设置为60000