1

我读过HttpMessageHandlers每 2 分钟回收一次,但我不确定是否将新的分配给现有的HttpClient

我已经通过使用进行了测试SetHandlerLifetime(TimeSpan.FromSeconds(5));,即使在 2 分钟后有无数请求,httpClient 仍在继续工作,这是一个好兆头?

这是否意味着我不必担心 DNS 更改/套接字耗尽?

ConfigureServices方法内部:

var myOptions = app.ApplicationServices.GetService<IOptionsMonitor<MyOptions>>();
HttpClient httpClient = app.ApplicationServices.GetService<IHttpClientFactory>().CreateClient();
MyStaticObject.Configure(myOptions, httpClient);

编辑:添加了一些示例代码。

4

2 回答 2

2

这里有几件事要看,第一件事MyStaticObject实际上需要是静态的吗?如果是这样,我建议将其注册为单例,以便您仍然可以利用依赖注入。完成此操作后,您可以IHttpClientFactory从代码中注册并使用它。您的ConfigureServices方法可能最终看起来像这样

public void ConfigureServices(IServiceCollection services)
{
  //The base extension method registers IHttpClientFactory
  services.AddHttpClient();
  services.AddSingleton<IMySingletonObject, MySingletonObject>();
}

然后在你的消费类中,MySingletonObject在这种情况下,你可以这样配置它

public class MySingletonObject
{
  private readonly IHttpClientFactory _clientFactory;

  public MySingletonObject(IHttpClientFactory clientFactory)
  {
    _clientFactory = clientFactory;
  }

  public async Task SomeMethodThatUsesTheClient()
  {
    var client = _clientFactory.CreateClient();
    //use the client
  }
}

这样做的原因是它IHttpClientFactory为我们处理了生命周期和池问题。根据文档

管理底层 HttpClientMessageHandler 实例的池和生命周期。自动管理避免了手动管理 HttpClient 生命周期时发生的常见 DNS(域名系统)问题。

这发生在您进行CreateClient调用时,因此您希望使用客户端在代码中执行此操作,而不是在应用程序启动时执行此操作。

作为旁注,如果您根本不需要这个类是单例,您可以使用扩展services.AddHttpClient<IMyClass, MyClass>()并将一个HttpClient直接注入到类中。DI 容器将在幕后为您处理从工厂获取客户端。

于 2020-03-06T15:00:39.073 回答
0
     public static IServiceCollection AddApiClient(this IServiceCollection services,
        Action<RgCommunicationClientOptions> action)
    {
        services.AddHttpClient<ISomeApiClient, SomeApiClient>()
            .AddPolicyHandler(GetRetryPolicy())
            .SetHandlerLifetime(TimeSpan.FromMinutes(4));
        services.AddOptions();
        services.Configure(action);

        return services;
    }
    
    static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
    {
        return HttpPolicyExtensions
            .HandleTransientHttpError()
            //.OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
            .WaitAndRetryAsync(2, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
    }

 services.AddApiClient(options => options.BaseAddress = configuration.GetSection("ExternalServices:SomeApi")["Url"]);
       

您可以通过依赖注入在类中注入上面的 HttpClient。我已经使用 Poly 扩展来添加 RetryPolicy。您还可以使用 SetHaandlerLifeTime 设置处理程序的 LifetTime。这样您就可以为每个客户端单独配置客户端。在日志中,您可以看到 httpHandler 在相应调用的 4 分钟后过期。我已经使用扩展方法来传递方法中的选项,通过应用程序设置获取值。希望这可以帮助。块引用

于 2021-02-10T10:42:10.707 回答