som*_*men 3 c# rate-limiting polly retry-logic
我有以下策略设置:
// Slack api for postMessage is generally 1 per channel per second.
// Some workspace specific limits may apply.
// We just limit everything to 1 second.
var slackApiRateLimitPerChannelPerSecond = 1;
var rateLimit = Policy.RateLimitAsync(slackApiRateLimitPerChannelPerSecond, TimeSpan.FromSeconds(slackApiRateLimitPerChannelPerSecond),
(retryAfter, _) => retryAfter.Add(TimeSpan.FromSeconds(slackApiRateLimitPerChannelPerSecond)));
Run Code Online (Sandbox Code Playgroud)
这应该:
我无法将其包装成第二个会重试的策略......
我可以像这样重试:
try
{
_policy.Execute(...)
}
catch(RateLimitedException ex)
{
// Policy.Retry with ex.RetryAfter
}
Run Code Online (Sandbox Code Playgroud)
但这似乎不对。
我想重试几次(3?)次,以便该方法更具弹性 - 我该怎么做?
我可能会迟到,但让我投入 2 美分。
该策略的引擎以无锁方式实现令牌桶算法。这有一个含义,所以它并不像你直觉想象的那样工作。
例如,从这个策略角度来看,每秒 1 个请求与每分钟 60 个请求相同。
实际上,后者不应该强制均匀分配(但确实如此)!所以,你不能像这样使用它:
对于 Polly,大多数保单都是无国籍的。这意味着两个执行不需要共享任何内容。
但对于断路器来说,控制器内部有一个状态。因此,您应该在多次执行中使用同一个实例。
在 Bulkhead 和 Rate Limiter 政策的情况下,状态并不那么明显。它们隐藏在实现中。但同样的规则也适用于此,您应该在多个线程之间共享相同的策略实例以实现所需的结果。
速率限制器本身可以在客户端和服务器端使用。服务器端可以主动拒绝过多的请求,以缓解过度泛洪。而客户端可以主动自我限制发出的请求,以遵守服务器和客户端之间的契约。
这个策略更适合服务器端(参见属性RetryAfter)。在客户端,速率门实现可能更合适,它通过利用队列和计时器来延迟传出请求。
如果重试和速率限制器都位于客户端
var retryPolicy = Policy
.Handle<RateLimitRejectedException>()
.WaitAndRetry(
3,
(int _, Exception ex, Context __) => ((RateLimitRejectedException)ex).RetryAfter,
(_, __, ___, ____) => { });
Run Code Online (Sandbox Code Playgroud)
如果重试位于客户端而速率限制器位于服务器端
var retryPolicy = Policy<HttpResponseMessage>
.HandleResult(res => res.StatusCode == HttpStatusCode.TooManyRequests)
.WaitAndRetry(
3,
(int _, DelegateResult<HttpResponseMessage> res, Context __)
=> res.Result.Headers.RetryAfter.Delta ?? TimeSpan.FromSeconds(0));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3697 次 |
| 最近记录: |