在 .NET 开发中,发出高效、可靠、且可伸缩的 Web 请求至关重要。过去,开发人员习惯直接使用 HttpClient
发出请求,这种方法看似简单:
var client = new HttpClient();
var response = await client.GetAsync("https://example.com");
var content = await response.Content.ReadAsStringAsync();
虽然这段代码简单有效,但随着应用规模增大和请求数量增多,开发者会遇到一些隐藏的性能问题。这些问题的根源在于对 HttpClient
的误用。
直接使用 HttpClient 的陷阱
套接字耗尽:每次为请求创建新实例时都会占用一个套接字。使用
HttpClient
后,它并不会立即释放套接字,因为连接进入TIME_WAIT
状态。在高负载情况下,这可能导致套接字耗尽,进而影响应用的连接能力。资源浪费:频繁创建和销毁
HttpClient
实例会浪费资源,导致不必要的开销和性能下降。配置不一致:管理多个
HttpClient
实例可能会导致请求间配置不一致,从而增加了全局策略(如超时、标头、错误处理等)的管理难度。
引入 HttpClientFactory
为了解决这些问题,.NET 推出了 HttpClientFactory
,它被认为是 Web 请求的最佳实践工具。HttpClientFactory
提供了以下优势:
高效的资源管理:
HttpClientFactory
维护一个实例池,可以重用实例,减少套接字耗尽和资源浪费。一致的配置:允许集中管理
HttpClient
实例配置,确保所有请求在标头、超时和其他策略上保持一致。弹性增强(与 Polly 集成):
HttpClientFactory
与 Polly(一个弹性和瞬态故障处理库)无缝集成,支持轻松实施重试策略、断路器等,从而增强了 HTTP 请求的稳健性。
使用 HttpClientFactory 和 Polly 进行实际测试
通过以下步骤,我们可以开始在应用程序中使用 HttpClientFactory
和 Polly:
1. 安装 Polly 包
首先确保已安装所需的 Polly NuGet 包:
Microsoft.Extensions.Http.Polly
Polly
2. 配置重试策略
定义一个使用 Polly 的重试策略,用于处理暂时性故障:
var retryPolicy = HttpPolicyExtensions.HandleTransientHttpError()
.WaitAndRetryAsync(
retryCount: 3, // 重试三次
sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)), // 指数退避:2、4、8秒
onRetry: (outcome, timespan, retryAttempt, context) =>
{
// 每次重试时的处理逻辑,例如日志记录
Console.WriteLine($"重试原因:{outcome.Exception?.Message}。等待时间:{timespan}。重试次数:{retryAttempt}。");
});
3. 注册 HttpClientFactory 并集成 Polly
在应用启动时注册 HttpClientFactory
和 Polly 策略:
builder.Services.AddHttpClient("ExampleClient", client =>
{
client.BaseAddress = new Uri("https://example.com");
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.Timeout = TimeSpan.FromSeconds(30); // 设置请求的全局超时时间
})
.AddPolicyHandler(retryPolicy); // 应用重试策略
4. 注入 HttpClientFactory 并调用 API
在服务或控制器中注入 IHttpClientFactory
实例,并使用它发送请求:
public class MyService
{
private readonly IHttpClientFactory _clientFactory;
public MyService(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public async Task<string> GetWebContentAsync(string url)
{
var client = _clientFactory.CreateClient("ExampleClient");
var response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
return content;
}
}
在此示例中,我们首先使用 Polly 定义了重试策略,指定在发生暂时性错误时最多重试三次,且每次重试的等待时间呈指数增长。然后,将策略与 HttpClientFactory
注册,并为名为 “ExampleClient” 的所有 HttpClient
实例应用该策略和配置。
使用 HttpClientFactory 的优势
弹性:通过优雅地处理暂时性故障,使应用程序更加稳定和健壮。 一致的配置: HttpClientFactory
创建的所有实例都共享相同的基址、标头和超时设置,确保全局一致性。高效的资源管理:优化了连接池和生命周期管理,减少了资源浪费和套接字耗尽的风险。
通过这种集成,HTTP 调用变得更可靠,同时简化了配置管理,使在整个 .NET 应用程序中实现复原策略更为便捷。
.NET绿叶社区
出处:https://leavescn.com/Articles/Content/3426
关注公众号↑↑↑:DotNet开发跳槽❀