限流 (v7.2.3 起)
翻译自:https://github.com/App-vNext/Polly/wiki/Rate-Limithttps://github.com/App-vNext/Polly/wiki/Rate-Limit
点此跳转到系列目录
https://blog.csdn.net/weixin_41957094/article/details/124854458
目标
提供一个策略,该策略限制在滚动时间窗口期间可执行的执行次数。
前提: '一个用户不应该垄断所有的资源'
限流 是一种常用的模式,用于控制在给定时间窗口内执行操作的速率。
限流的一个用例是帮助确保共享资源的公平使用,例如web服务器或数据库。如果将对web服务器的请求的速率限制分配给服务器的每个用户,那么就可以在不同的用户之间公平地共享资源。这有助于防止单个用户向服务器发出的请求超过服务器的合理用途,从而对其他用户的服务器性能造成不利影响。
在HTTP中,受速率限制的请求通常会给出一个HTTP 429太多请求状态码。这种请求的响应也可能包括一个Retry-After
响应头,告诉客户端在发出新请求之前需要等待多长时间。在Retry-After
报头值所表示的时间之前发出的进一步请求很可能会以相同的HTTP 429状态码失败。
一个你可能熟悉的使用速率限制的真实的例子是[GitHub API](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting“REST API中的资源- GitHub文档的速率限制”)。
语法
RateLimitPolicy rateLimit = Policy .RateLimit(20, TimeSpan.FromSeconds(1)); RateLimitPolicy<MyResult> rateLimitOfT = Policy .RateLimit<MyResult>(20, TimeSpan.FromSeconds(1));
上面的示例将创建一个速率限制策略,该策略将允许在1秒窗口内最多执行20次策略处理的任何操作。
上面的语法示例是同步;针对异步操作存在类似的异步重载:参见README和[wiki](asynchronous- action-execution).
参数
numberOfExecutions
: 每个时间跨度允许的正非零执行次数N
。perTimeSpan
:策略允许N
执行的频率。.maxBurst
(optional): :在一个突发中允许的最大执行数(例如,如果一段时间内没有执行)。retryAfterFactory
(optional): 当操作有速率限制时,为调用者表示建议的重试后时间的工厂
抛出的异常
RateLimitRejectedException
当执行被限流时抛出的异常. 所抛出的异常有一个RetryAfter
属性,其中包含一个TimeSpan
,该属性指定了向调用方建议的重试等待时间。
使用
每次策略执行成功,从当前时间段内限流策略可用的桶中使用一个_token_。随着当前时间窗口和执行的继续,token将继续从桶中扣除。
如果在窗口过期之前,桶中的令牌数量达到零,则策略的进一步执行将受到速率限制,并且在随后的每次执行中将向调用方抛出RateLimitRejectedException
异常。限流将持续到当前窗口的持续时间结束。
当当前窗口过期时,将在下一次执行时开始一个新的执行窗口,此时桶中的令牌数量将被重新填充。在前一个窗口期间被限制的任何请求现在将开始再次成功执行,直到重新填充的令牌桶再次耗尽。
这个令牌耗尽和补充的循环将随着策略的执行而继续。
果为策略配置了突发容量,则每个窗口将允许额外的执行次数,从而允许一定程度的不均匀使用。否则,时间窗口的可用执行次数将被涂抹均已,即,应用于策略的每个时间跨度的整个时间窗口的平均执行次数。
用法推荐
跨请求重用策略
策略应该跨请求重用,与断路器策略相同。否则,为每个请求创建的新的速率限制策略可能会产生这样的实际效果:如果它只在每个请求中使用一次,然后被丢弃,那么它就永远不会受到速率限制。
基于用户的分片速率限制
应该根据每个用户进行限流,比如根据用户ID共享相同的限流策略。否则,如果所有调用方通过特定策略平等地共享速率限制,则一个破坏性调用方可能导致通过该策略执行的所有调用方都受到速率限制。
这种行为可能会与首先使用限流的预期效果相反,允许一个行为不佳的客户端比在没有适当的限流政策的情况下过度使用自己的资源份额此时会更容易干扰到所有其他用户。
受保护资源的分片限流
另外,考虑用限流策略对希望保护的资源分割您的速率限制。例如,您可以为低资源占用的代码路径设置一个高速率限制,而为低资源占用的代码路径设置另一个低速率限制。
以这种方式对速率限制策略进行分片,允许您将由于速率限制到特定区域而导致的服务不可用范围扩大到某个用户,从而获得更好的总体用户体验。
例如,分离的读写速度限制web应用程序将限制活动中的用户点击一个按钮来执行写操作过于频繁,同时应用程序导航页面的UI渲染也不会被限流。
允许瞬时爆发
在创建速率限制策略时,请考虑配置瞬时爆发数量。 这可以防止所有策略的执行都遵循严格的每单位时间_X令牌_执行速率限制(允许在短时间内的高爆发)。
例如,允许每秒执行10次的限流策略将只允许每100毫秒执行一次成功。用户希望在一个应用程序执行一次操作在数短时间获取2份资源,这就需要用户在前后100毫秒分别执行,否则他们将被限流,即便没有速度限制这会仅需要20毫秒。
这种行为并不是我们想要的,因此配置适当的突发限制将允许行为良好的客户机在达到速率限制之前执行更多的执行。在本例中,如果突发执行速率为5,客户端可以在100毫秒内成功执行5次,而在这一秒内只有第7次执行受速率限制(初始突发执行5次,加上每100毫秒执行一次 公六次)。
线程安全与策略复用
线程安全
RateLimitPolicy
和AsyncRateLimitPolicy
的操作是线程安全的:多个调用可以通过一个策略实例安全地并发地进行。
策略复用
RateLimitPolicy
和AsyncRateLimitPolicy
实例旨可以多点复用。否则,对共享资源的速率限制将不会以您可能期望的方式应用。
翻译自:https://github.com/App-vNext/Polly/wiki/Rate-Limithttps://github.com/App-vNext/Polly/wiki/Rate-Limit