Laravel 作业在尝试使用油门时在 Redis 上失败



最终目标

目的是让我的应用程序向 Redis 队列发送可能大量电子邮件(此位正在工作(,然后 Redis 将这些电子邮件的处理限制为每选定的分钟数仅处理一组电子邮件。

对于此示例,我有一个将时间附加到文件的测试作业,并且我尝试将其限制为每 60 秒一次。

到目前为止的故事....

到目前为止,我已让应用程序成功地将 50 个作业的测试量推送到 Redis 队列。我可以登录到 Horizon 并在"进程作业"队列中看到这 50 个作业。我还可以登录 redis-cli 并在列表键"queues:processjob"下看到 50 个集。

我的问题是,一旦我尝试打开油门,只有 1 个作业运行,其余作业失败并显示以下错误:

Predis\Response\ServerException: ERR 运行脚本时出错(调用 f_29cc07bd431ccbf64637e5dcb60484560fdfa2da(: @user_script:10:WRONGTYPE 对/var/www/html/smhub/vendor/predis/predis/src/Client.php:370 中持有错误类型值的键进行操作

如果我移除油门,所有工作文件和 5 个作业都会立即运行。

我想可能是不正确的键名称,但如果我更改以下内容:

public function handle()
{
//
Redis::throttle('queues:processjob')->allow(1)->every(60)->then(function(){
Storage::disk('local')->append('testFile.txt',date("Y-m-d H:i:s"));
}, function (){
return $this->release(10);
});
}

对此:

public function handle()
{
//
Redis::funnel('queues:processjob')->limit(1)->then(function(){
Storage::disk('local')->append('testFile.txt',date("Y-m-d H:i:s"));
}, function (){
return $this->release(10);
});
}

那么一切正常。

我的想法...

有人告诉我,问题是 redis 键的类型是"列表",并且作业都在一个列表下。话虽如此,如果它不是这样工作的,我们将如何限制队列,因为限制需要一个唯一的键。

对于其他任何在尝试使其工作时遇到问题并且遇到与我相同的问题的人,这就是解决我的问题的原因:

故障

我以为Redis::throttle('queues:processjob')是指您想要限制的队列。但是,在重新阅读文档和代码测试后,我意识到事实并非如此。

修复

Redis::throttle('queues:processjob')旨在指向它自己的"保持"队列,因此必须是唯一的 Redis 键名称。因此,将其更改为Redis::throttle('throttle:queues:processjob')对我来说效果很好。

工作原理

当我第一次研究这个问题时,我假设Redis::throttle('this')限制了您指定的队列。在某种程度上,这是正确的,但如果作业是通过其他方式创建的,则它将无法工作。

Redis::throttle('this')实际上会创建一个新的"保持"队列,作业将在其中进行,直到满足您指定的条件。因此,在本例中,作业将转到队列"this",当释放限制触发器时,它们将被传递到其执行代码中指定的队列。在本例中,"queues:processjob"。

我希望这有帮助!

最新更新