Laravel 多个工作人员且速率受限

Laravel multiple workers and being rate limited

我有一个应用程序,它有一个包含多个工作人员的队列。工作人员根据队列中的作业数量进行缩放。工作人员正在处理的工作的要点之一是对外部服务进行 API 调用以检索一些数据。外部服务使用漏桶算法 (https://en.wikipedia.org/wiki/Leaky_bucket) 以每秒 2 次调用的速率实现 api 速率限制。我的 api 呼叫不是针对单个服务,而是针对该服务的帐户。因此,仅当我对服务帐户进行多次 api 调用时,速率限制才适用。不同帐户之间不共享速率限制。进行 api 调用的作业数以千计(仅针对一个帐户),因此存储桶总是满的,我将开始受到速率限制。

这样的问题是,如果我的工作在我达到它之前没有遵守速率限制,我可能会尝试延迟它们并在发生这种情况时将它们放回队列中,但因为我有多个工人并且成千上万的工作我可能会陷入速率限制的无限循环中。

我考虑过使用像 memcache 或 redis 这样的东西来存储一些可以在工作人员之间共享的信息,这样在我尝试在工作中进行 api 调用之前我会停止,延迟作业并将其放回队列中,这样就不会提高速率限制。这种方法的问题是,每次我做类似的事情时,我都会增加工作的尝试次数。我对每项工作的尝试次数有上限。我还意识到 Laravel worker 不能以任何方式改变尝试次数,我对此很好,我相信这会使 worker 更加稳定和可预测。重置尝试次数的唯一选择是删除作业并将其重新分配为新作业(但这感觉很乱)。

如果有人遇到过这样的问题,您是否愿意分享在这种情况下队列实现的样子? workers 是否应该在他们之间共享状态(这感觉不对)?

注意:我不认为让 worker 休眠是解决速率限制的好方法,因为我可能会 api 调用服务的不同帐户(基于什么作业在队列中排在下一个)因此,如果工作人员为一个帐户休眠而它可以为另一个帐户服务,这会让人感觉浪费了时间。

谢谢

听起来您正在使用 Shopify API?

我设法在 Laravel 5.5 中使用它来实现它。来自文档:

Redis::throttle('key')->allow(2)->every(1)->then(function () {
    // Job logic...
}, function () {
    // Could not obtain lock...

    return $this->release(10);
});

https://laravel.com/docs/5.5/queues#rate-limiting