天天看點

HttpClientFactory-向外請求的最佳

  • 它的元件包是Microsoft.Extensions.Http
  • 複原HttpClient帶來的問題

1|1HttpClient相關問題

  • 雖然HttpClient類實作了IDisposable,但不是首選在using語句中聲明和執行個體化它,因為釋放HttpClient對象時,基礎套接字不會立即釋放,這可能會導緻“套接字耗盡”問題 。是以,HttpClient 應進行一次執行個體化并在應用程式的生命周期中重複使用。 在負載較重的情況下,執行個體化每個請求的 HttpClient 類将耗盡可用的套接字數。 該問題會導緻 SocketException 錯誤。 要解決此問題,可能的方法是将 HttpClient 對象建立為單一對象或靜态對象,在長期運作的程序中使用 HttpClient 的共享執行個體時,開發人員遇到的另一個問題。 在将 HttpClient 執行個體化為單一執行個體或靜态對象的情況下,它無法處理 DNS 更改,但是,問題實際上不是 HttpClient 本身,而是 HttpClient 的預設構造函數,因為它建立了一個新的實際 HttpMessageHandler 執行個體,該執行個體具有上面提到的“套接字耗盡”和 DNS 更改問題 。

參考解決内容

1|2核心點

  • 管理内部HttpMessageHandler的生命周期,靈活應對資源問題和DNS重新整理問題。
  • 支援命名化,類型化配置,集中管理配置,避免沖突
  • 靈活的出站請求管道配置,輕松管理請求生命周期
  • 内置管道最外層和最記憶體日志記錄器,有Information和Trace輸出

1|3核心對象

  • HttpClient
  • HttpMessageHandler
  • SocketsHttpHandler
  • DelegatingHandler
  • IHttpClientFactory
  • IHttpClientBuilder

1|4使用方式

  • 基本用法
  • 命名用戶端模式
  • 類型化用戶端模式
  • 生成的用戶端

//首先,在Startup中的ConfigureService注冊我們的HttClient服務,僅僅一行代碼就可以搞定

service.AddHttpClien();

//接着,我們通過依賴注入來請求IHttpClientFactory,并建立HttpClient執行個體,以下代碼之後我們就可以放心使用HttpClient

public BasicUsageModel(IHttpClientFactory clientFactory)

{

_clientFactory = clientFactory;

}

public async Task OnGet()

var client = _clientFactory.CreateClient();

類型化用戶端

publi class XXXClient

IHttpClientFactory _httpclientFatory;

public XXXClient(IHttpClientFactory httpclientFatory)

{

_httpclientFatory=httpclientFatory;

}

public async Task<string> Get()

var client = _httpclientFatory.CreateClient();

return await client.GetStringAsync("xxx.url");

注冊

services.AddHttpClient<XXXClient>();

1|5出站請求中間件

  • HttpClient具有委托處理程式概念。

建立委托處理程式

  • 派生自DelegatingHandler (将 HTTP 響應消息的處理委托給另一處理程式(稱為“内部處理程式”)的 HTTP 處理程式的類型。)
  • 重寫SendAsync

代碼

public class xxxHandler : DelegatingHandler

{

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

{

//處理請求

var result = await base.SendAsync(request, cancellationToken); //調用内部handler

//處理響應

return result;

}

}

public void ConfigureServices(IServiceCollection services){

services.AddSingleton<xxxHandler>();

services.AddHttpClient("XXXServiceClient", client =>

{

client.DefaultRequestHeaders.Add("client-name", "namedclient");

client.BaseAddress = new Uri("https://localhost:5003");

}).SetHandlerLifetime(TimeSpan.FromMinutes(20))

.AddHttpMessageHandler(provider => provider.GetService<xxxHandler>());

services.AddScoped<xxxHandler>();

public class XXXServiceClient

IHttpClientFactory _httpClientFactory;

const string _clientName = "NamedOrderServiceClient"; //定義用戶端名稱

public XXXServiceClient(IHttpClientFactory httpClientFactory)

_httpClientFactory = httpClientFactory;

public async Task<string> Get()

var client = _httpClientFactory.CreateClient(_clientName); //使用用戶端名稱擷取用戶端

//使用client發起HTTP請求,這裡使用相對路徑來通路

return await client.GetStringAsync("/OrderService");

1|6生命周期

  • 每次對 IHttpClientFactory 調用 CreateClient 都會傳回一個新 HttpClient 執行個體。 每個命名用戶端都建立一個 HttpMessageHandler。 工廠管理 HttpMessageHandler 執行個體的生存期。
  • 處理程式的預設生存期為兩分鐘,可通過SetHandlerLifetime 重新設定。
下一篇: list對象去重

繼續閱讀