A HttpClient használatának irányelvei

Az System.Net.Http.HttpClient osztály HTTP-kéréseket küld, és HTTP-válaszokat fogad egy URI által azonosított erőforrástól. A HttpClient példányok az adott példány által végrehajtott összes kérésre alkalmazott beállítások gyűjteményei, és minden példány saját kapcsolatkészletet használ, amely elkülöníti a kéréseket másoktól. A .NET Core 2.1-től kezdve az osztály biztosítja a SocketsHttpHandler megvalósítást, így a viselkedés minden platformon konzisztens.

DNS-viselkedés

HttpClient csak kapcsolat létrehozásakor oldja fel a DNS-bejegyzéseket. A DNS-kiszolgáló által megadott élettartamokat (TTL) nem követi nyomon. Ha a DNS-bejegyzések rendszeresen változnak, ami bizonyos esetekben előfordulhat, az ügyfél nem fogja tiszteletben tartani ezeket a frissítéseket. A probléma megoldásához a tulajdonság beállításával PooledConnectionLifetime korlátozhatja a kapcsolat élettartamát, hogy a DNS-keresés ismétlődjön a kapcsolat cseréjekor. Vegyük a következő példát:

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

A fenti HttpClient beállítás a kapcsolatok 15 percig történő újrafelhasználására van konfigurálva. A megadott PooledConnectionLifetime idő eltelte után a kapcsolat lezárul, és létrejön egy új.

Készletezett kapcsolatok

Az egyhez HttpClient tartozó kapcsolatkészlet az alapul szolgálóhoz SocketsHttpHandlervan csatolva. HttpClient A példány megsemmisítése után az összes meglévő kapcsolatot a készleten belül megsemmisíti. Ha később ugyanahhoz a kiszolgálóhoz küld egy kérelmet, új kapcsolatot kell létrehozni. Ennek eredményeképpen teljesítménybeli büntetés jár a szükségtelen kapcsolatlétrehozásért. Ezenkívül a TCP-portok nem lesznek azonnal felszabadítva a kapcsolat bezárása után. (Erről további információt az RFC 9293 TCP-ben TIME-WAITtalál.) Ha a kérelmek száma magas, az elérhető portok operációsrendszer-korlátja kimerülhet. A portkimerülési problémák elkerülése érdekében javasoljuk, hogy a lehető legtöbb HTTP-kéréshez használjon HttpClient újra példányokat.

Az élettartam-kezelés szempontjából javasolt HttpClient használat összegzéséhez használjon hosszú élettartamú ügyfeleket, és állítsa be PooledConnectionLifetime a (.NET Core és .NET 5+) vagy a rövid élettartamú ügyfeleket.IHttpClientFactory

  • A .NET Core-ban és a .NET 5+-ban:

    • A várt DNS-változásoktól függően használjon egy static vagy egypéldányosHttpClient példányt PooledConnectionLifetime a kívánt időközre( például 2 perc). Ez a portkimerüléssel és a DNS-módosításokkal kapcsolatos problémákat is megoldja anélkül, hogy hozzáadja a terhelést.IHttpClientFactory Ha ki kell tudnia másolni a kezelőt, külön regisztrálhatja.

    Tipp.

    Ha csak korlátozott számú HttpClient példányt használ, az is elfogadható stratégia. A lényeg az, hogy nincsenek létrehozva és megsemmisítve az egyes kérésekkel, mivel mindegyik tartalmaz egy kapcsolatkészletet. Több példány használata több proxyval rendelkező forgatókönyvekhez vagy a cookie-tárolók elkülönítéséhez szükséges anélkül, hogy teljesen letiltanák a cookie-k kezelését.

    • A használatával IHttpClientFactorytöbb, eltérően konfigurált ügyfél is lehet a különböző használati esetekhez. Vegye azonban figyelembe, hogy a gyári ügyfelek rövid élettartamúak, és az ügyfél létrehozása után a gyár már nem rendelkezik felette.

      A gyári készletek HttpMessageHandler példányai, és ha az élettartama nem járt le, a kezelők újra felhasználhatók a készletből, amikor a gyár létrehoz egy új HttpClient példányt. Ez az újrahasználat elkerüli a szoftvercsatornák kimerülési problémáit.

      Ha a konfigurálhatóságra van szüksége, javasoljuk, hogy IHttpClientFactory a gépelt ügyfél megközelítést használja.

  • A .NET-keretrendszer a példányok kezelésére HttpClient használhatóIHttpClientFactory. Ha nem használja a gyárat, és ehelyett saját maga hoz létre egy új ügyfélpéldányt az egyes kérésekhez, kimerítheti az elérhető portokat.

    Tipp.

    Ha az alkalmazás cookie-kat igényel, fontolja meg az automatikus cookie-kezelés letiltását vagy elkerülését IHttpClientFactory. A példányok készletezése HttpMessageHandler az objektumok megosztását CookieContainer eredményezi. A nem várt CookieContainer objektummegosztás gyakran helytelen kódot eredményez.

Az élettartam kezelésével HttpClientIHttpClientFactorykapcsolatos további információkért tekintse meg azIHttpClientFactoryirányelveket.

Rugalmasság statikus ügyfelekkel

Az alábbi minta használatával konfigurálhat egy static vagy egyetlenton ügyfélt tetszőleges számú rugalmassági folyamat használatára:

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);

A fenti kód a következőket végzi el:

  • A Microsoft.Extensions.Http.Resilience NuGet-csomagra támaszkodik.
  • Egy átmeneti HTTP-hibakezelőt ad meg, amely újrapróbálkozási folyamattal van konfigurálva, amely minden kísérlet esetén exponenciálisan késlelteti a késleltetési időközöket.
  • A készletezett kapcsolat tizenöt perces élettartamát határozza meg a socketHandler.
  • Átadja az socketHandlerresilienceHandler újrapróbálkozással kapcsolatos logikát.
  • Példányosít egy HttpClient adott a resilienceHandler.

Fontos

A Microsoft.Extensions.Http.Resilience kódtár jelenleg kísérletiként van megjelölve, és a jövőben változhat.

Lásd még