我有一个“密钥”,当密钥在 1 分钟内达到其配额(1 分钟存储桶不是滑动窗口)端点时,我可以每分钟调用 500 次休息端点(每个密钥可以是 200、300 或 500)返回带有等待延迟的 429(速率受限)。一旦延迟过去,我可以再次使用这个键。
我的 API 是一种代理(客户端调用我的 API,我的 API 通过提供其中一个密钥来调用其他服务)我的 API 将堆叠我所有的用户密钥,这样在某种意义上它就变成了一个大密钥。并且当我的客户中的“任何”调用我的 api 时,我的系统会巧妙地选择 1 个仍然具有配额的键,并且当该键达到配额时,它会将其从可用键列表、队列或任何结构中删除
我很难为它选择一个好的数据结构和逻辑。我想到的是这样的
1) 获得一个仍然有配额并且至少有 1 个剩余通话可用的密钥 -1a) 如果没有可用的密钥,只需“等待”直到有一个可用
2)调用端点
3) 减少 1 的密钥配额,如果密钥受到速率限制,则将其从“队列”或“列表”或其他任何内容中删除。
4)回到1
请注意,我的 API 调用的端点会返回有用的信息,例如“requestRemaining”,这些信息指示密钥在受到速率限制之前还剩下多少请求。“速率延迟”指示何时可以再次使用密钥,以防它受到速率限制。
我认为一个好的解决方案是主动了解密钥何时会受到速率限制,而不是仅依赖端点响应。像这样,我们避免使用已达到配额的密钥“免费”调用端点。
我已经尝试过使用 DelayQueue 和一些信号量来阻止没有可用的密钥,但是我有一个问题,提前知道密钥是否会受到速率限制。我想在“请求”级别而不是关键级别并发。这意味着我不希望客户端在发出请求之前锁定密钥。如果一个密钥的配额为 500,我希望最多 500 个并发客户端使用 1 个单一密钥;
我很乐意听取更有经验的人的意见,了解他们将如何解决这个问题。