C# Polly 结合了在 HttpClient 内部使用的 http 错误处理程序、重试、舱壁和超时

标签 c# dotnet-httpclient polly retry-logic policywrap

我正在尝试进行一些 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/

相关文章:

.net - 使用HttpClient在PostAsync之后处理对象

c# - 如何将 PolicyHttpMessageHandler 用作 "standalone"?

c# - 使用 Polly 重试之前正确的日志记录方法是什么

c# - 在 C# 中处理嵌套的 "using"语句

c# - mvc同一站点的多个路由

c# - Mongodb .Net Driver 如何关闭连接

c# - 内容 header 和 header 有什么区别?

c# - PostAsJsonAsync 未按预期运行

c# - Polly WaitAndRetryAsync 在重试一次后挂起

c# - 如何在没有 BOM 的情况下使用 UTF8 而不是 UTF8 编写 XML?