在构建高可用的微服务或分布式系统时,HTTP 请求的可靠性至关重要。.NET Core 提供了 IHttpClientFactory 来管理 HttpClient 实例,而 Polly 则是一个强大的库,用于实现重试、断路器、超时等容错策略。将二者结合使用,可以有效提升应用的健壮性。
为何使用 IHttpClientFactory?
在早期版本的 .NET 中,直接创建 HttpClient 实例可能导致套接字耗尽等问题。IHttpClientFactory 通过集中管理 HttpClient 实例,避免了这些问题,并提供了更好的可测试性和可配置性。
引入 Polly 实现容错策略
Polly 是一个 .NET 的容错和瞬态故障处理库,支持重试、断路器、超时等策略。与 IHttpClientFactory 配合使用,可以为 HTTP 请求添加多种容错机制。
1. 安装必要的 NuGet 包
首先,确保安装了以下 NuGet 包:
dotnet add package Microsoft.Extensions.Http.Polly
2. 配置重试策略
在 Program.cs 或 Startup.cs 中,配置带有重试策略的 HttpClient:
builder.Services.AddHttpClient<IBasketService, BasketService>()
.SetHandlerLifetime(TimeSpan.FromMinutes(5))
.AddPolicyHandler(HttpPolicyExtensions
.HandleTransientHttpError()
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))));
上述代码配置了一个指数退避的重试策略,当遇到瞬态错误时,最多重试 3 次,每次重试的间隔时间呈指数增长。
3. 配置断路器策略
为了防止系统在外部服务不可用时继续发起请求,可以添加断路器策略:
builder.Services.AddHttpClient<IBasketService, BasketService>()
.SetHandlerLifetime(TimeSpan.FromMinutes(5))
.AddPolicyHandler(HttpPolicyExtensions
.HandleTransientHttpError()
.CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)));
此配置表示在连续 5 次失败后,断路器将打开 30 秒,期间不再发起请求。
Polly 最佳实践建议
- 使用命名或类型化客户端:通过命名或类型化的方式配置 HttpClient,可以实现更清晰的配置和更好的可维护性。
- 避免手动创建 HttpClient 实例:应通过 IHttpClientFactory 创建 HttpClient 实例,避免直接使用构造函数。
- 设置适当的超时时间:为 HttpClient 设置合理的超时时间,防止请求长时间挂起。
- 日志记录和监控:启用日志记录和监控,及时发现和响应异常情况。
常见问题和误区
- 过度重试:设置过多的重试次数可能导致系统负载增加,应根据实际情况合理配置。
- 忽视非瞬态错误:Polly 默认处理瞬态错误,但对于非瞬态错误(如 4xx 状态码),应根据业务需求决定是否处理。
- 共享 HttpClient 实例:虽然 IHttpClientFactory 会管理 HttpClient 的生命周期,但共享同一个实例可能导致请求之间的干扰,应谨慎使用。
通过合理配置 IHttpClientFactory 和 Polly,可以显著提升 .NET Core 应用的 HTTP 请求的可靠性和性能。在实际开发中,应根据业务需求灵活调整策略,确保系统的高可用性。