【发布时间】:2017-09-27 05:32:49
【问题描述】:
我有一个应用程序,它有一个包含多个工作人员的队列。工作人员根据队列中的作业数量进行缩放。工作人员正在处理的工作的要点之一是对外部服务进行 API 调用以检索一些数据。外部服务使用漏桶算法(https://en.wikipedia.org/wiki/Leaky_bucket)以 2 次调用/秒的速率实现 api 速率限制。我的 api 调用不是针对单个服务,而是针对该服务的帐户。因此,速率限制仅适用于我对服务帐户进行多次 api 调用时。不同账户之间不共享速率限制。进行 api 调用的作业数量有数千个(仅针对一个帐户),因此存储桶总是会满的,我将开始受到速率限制。
这样的问题是,如果我的工作在达到速率限制之前没有遵守,我可能会尝试延迟它们并在发生这种情况时将它们放回队列中,但因为我有多个工人和数千个我可能会陷入无限循环的速率限制。
我考虑过使用 memcache 或 redis 之类的东西来存储某种可以在工作人员之间共享的信息,以便在我尝试在作业中进行 api 调用之前,我会停止、延迟作业并将其放置回到队列中,这样它就不会提高速率限制。这种方法的问题在于,每次我做类似的事情时,我都会增加工作的尝试次数。我有每个工作的最大尝试次数。我还意识到 Laravel worker 的尝试次数不能以任何方式改变,我对此很好,我相信这会使 worker 更加稳定和可预测。重置该尝试次数的唯一选择是删除该作业并将其作为新作业重新调度(但这感觉非常混乱)。
如果有人遇到过这样的问题,您愿意分享在这种情况下队列实现的样子吗?工人是否应该在他们之间共享状态(这感觉不对)?
注意:我不认为让工作人员睡觉是解决速率限制的好方法,因为我可能会对服务的不同帐户进行 api 调用(基于队列中的下一个作业) 因此,如果工人为一个帐户睡觉,而它可以为另一个帐户提供服务,这将感觉浪费了时间。
谢谢
【问题讨论】:
标签: laravel queue jobs worker rate-limiting