.NET使用HttpClientFactory和Polly 替代直接调用HttpClient的优势

科技   2024-11-09 08:16   北京  

在 .NET 开发中,发出高效、可靠、且可伸缩的 Web 请求至关重要。过去,开发人员习惯直接使用 HttpClient 发出请求,这种方法看似简单:

var client = new HttpClient();  
var response = await client.GetAsync("https://example.com");  
var content = await response.Content.ReadAsStringAsync();

虽然这段代码简单有效,但随着应用规模增大和请求数量增多,开发者会遇到一些隐藏的性能问题。这些问题的根源在于对 HttpClient 的误用。


直接使用 HttpClient 的陷阱

  1. 套接字耗尽:每次为请求创建新实例时都会占用一个套接字。使用 HttpClient 后,它并不会立即释放套接字,因为连接进入 TIME_WAIT 状态。在高负载情况下,这可能导致套接字耗尽,进而影响应用的连接能力。

  2. 资源浪费:频繁创建和销毁 HttpClient 实例会浪费资源,导致不必要的开销和性能下降。

  3. 配置不一致:管理多个 HttpClient 实例可能会导致请求间配置不一致,从而增加了全局策略(如超时、标头、错误处理等)的管理难度。


引入 HttpClientFactory

为了解决这些问题,.NET 推出了 HttpClientFactory,它被认为是 Web 请求的最佳实践工具。HttpClientFactory 提供了以下优势:

  1. 高效的资源管理HttpClientFactory 维护一个实例池,可以重用实例,减少套接字耗尽和资源浪费。

  2. 一致的配置:允许集中管理 HttpClient 实例配置,确保所有请求在标头、超时和其他策略上保持一致。

  3. 弹性增强(与 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<stringGetWebContentAsync(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 的优势

  1. 弹性:通过优雅地处理暂时性故障,使应用程序更加稳定和健壮。
  2. 一致的配置HttpClientFactory 创建的所有实例都共享相同的基址、标头和超时设置,确保全局一致性。
  3. 高效的资源管理:优化了连接池和生命周期管理,减少了资源浪费和套接字耗尽的风险。

通过这种集成,HTTP 调用变得更可靠,同时简化了配置管理,使在整个 .NET 应用程序中实现复原策略更为便捷。

.NET绿叶社区

出处:https://leavescn.com/Articles/Content/3426


关注公众号DotNet开发跳槽    

DotNet开发跳槽
本公众号专注为.net开发工程师提供一个学习技术及求职/跳槽的交流平台。不定期分享NET技术类文章、面试题、求助技巧等干货,原创文章300+篇,让.net开发工程师学习/面试不再迷茫。ps: 后台回复“跳槽”,免费领取.NET开发面试题!
 最新文章