HttpClient 使用方針

System.Net.Http.HttpClient 類型傳送 HTTP 要求並從由 URI 識別之資源接收 HTTP 回應。 HttpClient 執行個體是套用至該執行個體執行的所有請求的設定集合,每個執行個體都使用自己的連線集區,將自己的請求與其他請求隔離開來。 從 .NET Core 2.1 開始,SocketsHttpHandler 類別會提供實作,讓所有平台的行為保持一致。

DNS 行為

HttpClient 僅會在連線建立後,解析 DNS 項目。 它不會追蹤 DNS 伺服器所指定的任何存留時間 (TTL) 長度。 如果 DNS 項目定期變更 (在某些情況下可能會發生),用戶端將不會遵守這些更新。 若要解決此問題,您可以透過設定 PooledConnectionLifetime 屬性,限制連線的存留期,以便在替代連線時重複 DNS 查閱。 請考慮下列範例:

var handler = new SocketsHttpHandler
{
    PooledConnectionLifetime = TimeSpan.FromMinutes(15) // Recreate every 15 minutes
};
var sharedClient = new HttpClient(handler);

上述 HttpClient 會設定為重複使用連線 15 分鐘。 經過 PooledConnectionLifetime 指定的時間範圍之後,就會關閉連線,並建立新的連線。

集區式連線

HttpClient 的連線集區會連結至基礎 SocketsHttpHandler。 當您處置 HttpClient 執行個體時,其會處置集區內的所有現有連線。 如果您稍後將要求傳送至相同的伺服器,則必須重新建立新的連線。 因此,不必要的連線建立會產生效能損失。 此外,連線關閉之後,不會立即釋放 TCP 連接埠。 (如需詳細資訊,請參閱 RFC 9293 中的 TCP TIME-WAIT。)如果要求率很高,則可能會耗盡可用連接埠的作業系統限制。 若要避免連接埠耗盡問題,建議您盡可能重複使用多個 HTTP 要求的 HttpClient 執行個體。

為了摘要說明在存留期管理方面的建議 HttpClient 使用方式,您應該使用長期客戶端並設定 PooledConnectionLifetime (.NET Core 和 .NET 5+) 或 IHttpClientFactory 建立的短期用戶端。

  • 在 .NET Core 和 .NET 5+:

    • 根據預期的 DNS 變更,使用 static單一資料庫HttpClient執行個體,並將 PooledConnectionLifetime 設定為所需的間隔,例如 2 分鐘。 這可解決連接埠耗盡和 DNS 變更問題,而不會增加 IHttpClientFactory 的額外負荷。 如果您需要模擬處理常式的能力,可以個別註冊處理常式。

    提示

    如果您只使用有限的 HttpClient 執行個體數目,這也是可接受的策略。 此處的重點在於,並不會隨著每個要求而建立及處置這些執行個體,因為其每一個都包含連線集區。 多個 Proxy 的案例需要使用多個執行個體,或分隔 Cookie 容器,而不需完全停用 Cookie 處理。

    • 您可以使用 IHttpClientFactory,針對不同的使用案例,有多個不同設定的用戶端。 不過,請注意,處理站建立的用戶端為短期有效,一旦建立用戶端後,處理站就無法再進行控制。

      處理站集區 HttpMessageHandler 執行個體,如果其存留期尚未過期,當處理站建立新的 HttpClient 執行個體時,可以從集區重複使用處理程式。 此重複使用可避免任何通訊端耗盡問題。

      如果您想要取得 IHttpClientFactory 提供的可設定性,建議您使用具型別的用戶端方法

  • 在 .NET Framework 中,使用 IHttpClientFactory 來管理您的 HttpClient 執行個體。 如果您未使用處理站,而是自行為每個要求建立新的用戶端執行個體,則可能會耗盡可用的連接埠。

    提示

    如果您的應用程式需要 Cookie,請考慮停用自動 Cookie 處理或避免 IHttpClientFactory。 共用 HttpMessageHandler 執行個體會導致共用 CookieContainer 物件。 未預期的 CookieContainer 物件共用通常會導致程式碼不正確。

如需使用 IHttpClientFactory 管理 HttpClient 存留期的詳細資訊,請參閱 IHttpClientFactory 指導方針

使用靜態客戶端的復原能力

您可以使用下列模式,將 static 或單一資料庫用戶端設定為使用任意數目的復原管線:

using System;
using System.Net.Http;
using Microsoft.Extensions.Http;
using Microsoft.Extensions.Http.Resilience;
using Polly;

var retryPipeline = new ResiliencePipelineBuilder<HttpResponseMessage>()
    .AddRetry(new HttpRetryStrategyOptions
    {
        BackoffType = DelayBackoffType.Exponential,
        MaxRetryAttempts = 3
    })
    .Build();

var socketHandler = new SocketsHttpHandler
{
    PooledConnectionLifetime = TimeSpan.FromMinutes(15)
};
var resilienceHandler = new ResilienceHandler(retryPipeline)
{
    InnerHandler = socketHandler,
};

var httpClient = new HttpClient(resilienceHandler);

上述 程式碼:

  • 依賴 Microsoft.Extensions.Http.Resilience NuGet 套件。
  • 指定暫時性 HTTP 錯誤處理常式,使用重試管線進行設定,而每個嘗試都會以指數方式輪詢延遲間隔。
  • 定義的 socketHandler 集區連線存留期為15分鐘。
  • 使用重試邏輯將 socketHandler 傳遞至 resilienceHandler
  • 具現化具有指定 resilienceHandlerHttpClient

重要

連結 Microsoft.Extensions.Http.Resilience 庫目前標示為 實驗性 ,未來可能會變更。

另請參閱