首页 > 后端开发 > 戈兰 > 正文

控制传出速率限制

WBOY
发布: 2024-07-29 08:03:13
原创
661 人浏览过

让我们想象一个场景,有一个与第三方 API 交互的分布式应用程序。通常,第三方 API 具有速率限制控制机制,以避免其客户端突发请求并导致服务停机。在这样的场景下,调用者如何在分布式环境中控制向第三方API发出请求的速率?这篇文章讨论了解决这个问题的可能策略。

控制请求速率的算法有很多种,但这里我们重点介绍令牌桶算法,因为它相对容易理解和实现。该算法规定:一个桶最多可以容纳T个令牌,当应用程序想要向第三方API发出请求时,它必须从桶中取出1令牌。如果桶是空的,则必须等到桶中至少有1令牌。此外,桶会以 R 令牌/毫秒的固定速率重新填充 1 令牌。

令牌桶算法非常容易理解,但是如何在分布式环境中使用它来控制对第三方 API 的传出请求?

如果想要在分布式环境中控制传出速率限制,则需要当前速率限制的集中式事实来源。有多种方法可以实现事实来源,我用可能的实现理想化了下图:

Controlling outgoing rate limit

上图中,我们有一个分布在多个pod中的应用程序,每个pod都可以向第三方API发出请求。在应用基础设施中,有一个TCP服务器,通过令牌桶算法来控制速率限制。在向第三方 API 发出请求之前,pod 会向 TCP 服务器请求新的令牌,并且 pod 会等待 TCP 服务器的响应,直到至少有一个可用令牌。令牌可用后,Pod 向第三方 API 发出请求。

TCP 服务器实现可以在这个存储库 https://github.com/rafaquelhodev/rlimit/ 中找到,在下一节中我将简要讨论 golang 中的令牌桶实现。

令牌桶实现

下面,我展示了令牌桶实现背后的主要思想。请查看 https://github.com/rafaquelhodev/rlimit/ 存储库以了解详细的实现。

速率限制控制集中在TokenBucket结构体中:

雷雷

你可以注意到TokenBucket结构体中有一个subs属性。基本上,这是特定令牌桶的订阅者数组:每次客户端请求令牌时,客户端都会添加到 subs 数组中,并且当新令牌添加到存储桶时会通知客户端。

启动桶时,我们需要提供桶可以支持的最大令牌数(maxTokens)以及令牌添加到桶中的时间量(refillPeriod):

雷雷

现在,您可能想知道“如何将令牌添加到存储桶中?”。为此,当创建存储桶时,会启动一个 cron 作业,并在每个 refillPeriod 毫秒时,将一个新令牌添加到存储桶中:

雷雷

最后,当客户端想要从桶中获取令牌时,必须调用 waitAvailable 函数:

雷雷

灵感来自 https://github.com/Mohamed-khattab/Token-bucket-rate-limiter

以上是控制传出速率限制的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!