laravel redis队列忽略限制

0qx6xfy6  于 2021-06-10  发布在  Redis
关注(0)|答案(1)|浏览(522)

我用的是拉威尔地平线和redis,我正试图控制它。我使用的外部api的速率限制为每分钟100个请求。我需要提出大约700个请求。我对它进行了设置,以便添加到队列中的每个作业只在作业本身中执行一个api调用。因此,如果我限制队列,我应该能够保持在限制之内。由于某些原因,没有发生限制,而是通过队列进行限制(因此当然会触发许多api错误)。但是,节流阀在本地工作,而不是在我的服务器上。
我最初试图限制每个laravel的队列文档,但只能让它在本地工作,所以我改为在github上尝试laravel队列速率限制包。根据自述,我添加了以下内容到我的 queue.php 配置文件:

'rateLimits' => [
        'default' => [ // queue name
            'allows' => 75, // 75 job
            'every' => 60 // per 60 seconds
        ]
    ],

由于某些原因,当我在本地ubuntu环境中运行节流时,它可以正常工作,但在我的服务器(也是ubuntu)上不工作。在服务器上,它只是在队列中穿行,就好像没有节流阀一样。
有没有什么地方我做错了,或者有没有更好的方法来处理速率受限的外部api?
编辑1:
配置/horizon.php

'environments' => [
        'production' => [
            'supervisor-1' => [
                'connection' => 'redis',
                'queue' => ['default'],
                'balance' => 'simple',
                'processes' => 3,
                'tries' => 100,
            ],
        ],

启动大多数作业的手柄之一:

public function handle()
    {
        $updatedPlayerIds = [];
        foreach ($this->players as $player) {
            $playerUpdate = Player::updateOrCreate(
                [
                    'id' => $player['id'],
                ],
                [
                    'faction_id' => $player['faction_id'],
                    'name' => $player['name'],
                ]
            );

            // Storing id's of records updated
            $updatedPlayerIds[] = $playerUpdate->id;

            // If it's a new player or the player was last updated awhile ago, then get new data!
            if ($playerUpdate->wasRecentlyCreated ||
                $playerUpdate->last_complete_update_at == null ||
                Carbon::parse($playerUpdate->last_complete_update_at)->diffInHours(Carbon::now()) >= 6) {
                Log::info("Updating '{$playerUpdate->name}' with new data", ['playerUpdate' => $playerUpdate]);
                UpdatePlayer::dispatch($playerUpdate);
            } else {
//                Log::debug("Player data fresh, no update performed", ['playerUpdate' => $playerUpdate]);
            }
        }

        //Delete any ID's that were not updated via the API
        Player::where('faction_id', $this->faction->id)->whereNotIn('id', $updatedPlayerIds)->delete();
    }

另外,这里有一个粗略的图表,我试图说明如何在短时间内生成多个job php文件,特别是像 updatePlayer() 通常产卵700次。

gc0ot86w

gc0ot86w1#

看起来你提到的包(laravel queue rate limit)在horizon上不太好用。你最好使用laravel的内置方法。
在laravel的队列中,添加 ->block(60) 匹配 ->every(60) 这样默认超时就不会在60秒之前启动并调用另一个回调。

Redis::throttle('torn-api')->allow(75)->every(60)->block(60)

另外,考虑将timeout和max retry值添加到horizon的配置中 (config/horizon.php) . 您还可以使用 failed 方法。看看这个。
retry_after 以及 timeout 地平线配置中的值。你的 retry_after 配置中的值应始终大于执行作业所需的时间。以及 timeout 值应该比 retry_after 价值观。”这将确保处理给定作业的工人总是在重试作业之前被杀死。

相关问题