我正在尝试进行一些 HTTP 调用,并且希望具有重试、超时和隔离功能以实现最大并发连接数。这是我的尝试。我不知道 WrapAsync
函数调用的顺序是否正确。更具体地说,
- 我有时可能会从服务器收到 4xx 或 5xx 响应,我希望 Polly 处理这些
- 我不希望
HttpClient
进行超过 3 个并发 HTTP 调用,并且我将队列大小设置为“无限” - 如果服务器在 20 秒内没有响应,则该尝试超时
- 对于重试,通过以指数方式增加超时来使用指数超时策略
我的问题是这段代码是否按照我的想法执行?
var betterPolicy = HttpPolicyExtensions.HandleTransientHttpError().OrTransientHttpStatusCode()
.WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)))
.WrapAsync(Policy.BulkheadAsync(3, int.MaxValue /* queue size */))
.WrapAsync(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(20)));
var httpClient = new HttpClient(new PolicyHttpMessageHandler(betterPolicy));
最佳答案
对于 Polly,有多种方法可以组合/链接策略。 Here我已经演示了最常见的。我强烈鼓励您使用 Policy.WrapAsync
静态方法,因为:
- 更容易解释escalation chain :
- 最左边的参数是最外层的策略
- 最右边的参数是最内部的策略
- 它强制执行编译时策略兼容性检查
var resilienceStrategy = Policy.WrapAsync(sharedBulkhead, localRetry, localTimeout);
在 Bulkhead 策略的情况下,我使用了前缀 shared
,因为它需要在 HttpClient
调用之间共享,否则它是无用的。对于 Polly,大多数策略都是无状态的,但也有一些 stateful (如断路器或隔板)。
我还建议阅读this other post of mine其中详细介绍了如何在 HttpClient
情况下强制进行限制。长话短说:Bulkhead主要是设计for CPU based computations ,不适用于 I/O 绑定(bind)操作。 RateLimit政策可能更适合这一点。
关于C# Polly 结合了在 HttpClient 内部使用的 http 错误处理程序、重试、舱壁和超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76987685/