Delen via


Richtlijnen voor het gebruik van HttpClient

De System.Net.Http.HttpClient klasse verzendt HTTP-aanvragen en ontvangt HTTP-antwoorden van een resource die is geïdentificeerd door een URI. Een HttpClient exemplaar is een verzameling instellingen die wordt toegepast op alle aanvragen die door dat exemplaar worden uitgevoerd, en elk exemplaar maakt gebruik van een eigen verbindingsgroep, waarmee de aanvragen van anderen worden geïsoleerd. Vanaf .NET Core 2.1 biedt de SocketsHttpHandler klasse de implementatie, waardoor gedrag consistent is voor alle platforms.

DNS-gedrag

Alleen HttpClient zet DNS-vermeldingen om wanneer er een verbinding wordt gemaakt. Er wordt geen time to live -duur (TTL) bijgehouden die is opgegeven door de DNS-server. Als DNS-vermeldingen regelmatig veranderen, wat in sommige scenario's kan gebeuren, respecteert de client deze updates niet. U kunt dit probleem oplossen door de levensduur van de verbinding te beperken door de PooledConnectionLifetime eigenschap in te stellen, zodat dns-zoekacties worden herhaald wanneer de verbinding wordt vervangen. Kijk een naar het volgende voorbeeld:

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

Het voorgaande HttpClient is geconfigureerd om verbindingen gedurende 15 minuten opnieuw te gebruiken. Nadat de tijdsperiode PooledConnectionLifetime is verstreken en de verbinding de laatste gekoppelde aanvraag (indien van toepassing) heeft voltooid, wordt deze verbinding gesloten. Als er aanvragen in de wachtrij staan, wordt er indien nodig een nieuwe verbinding gemaakt.

Het interval van 15 minuten is willekeurig gekozen voor illustratiedoeleinden. Kies de waarde op basis van de verwachte frequentie van DNS- of andere netwerkwijzigingen.

Gegroepeerde verbindingen

De verbindingsgroep voor een HttpClient is gekoppeld aan de onderliggende SocketsHttpHandlergroep. Wanneer het HttpClient exemplaar wordt verwijderd, worden alle bestaande verbindingen in de pool verwijderd. Als u later een aanvraag naar dezelfde server verzendt, moet er een nieuwe verbinding worden gemaakt. Als gevolg hiervan is er een prestatiestraf voor het maken van onnodige verbindingen. Bovendien worden TCP-poorten niet onmiddellijk na het afsluiten van de verbinding vrijgegeven. (Zie TCP TIME-WAIT in RFC 9293 voor meer informatie hierover.) Als de frequentie van aanvragen hoog is, is de limiet van het besturingssysteem van beschikbare poorten mogelijk uitgeput. Om problemen met poortuitputting te voorkomen, raden we u aan instanties voor zoveel mogelijk HTTP-aanvragen te hergebruiken HttpClient .

Als u het aanbevolen HttpClient gebruik wilt samenvatten in termen van levensduurbeheer, moet u óf clients met een lange levensduur gebruiken en PooledConnectionLifetime, óf clients met een korte levensduur gebruiken die zijn gemaakt door IHttpClientFactory.

  • In .NET Core en .NET 5+:

    • Gebruik een static of singleton-exemplaarHttpClient met PooledConnectionLifetime de waarde ingesteld op het gewenste interval, zoals 2 minuten, afhankelijk van de verwachte DNS-wijzigingen. Dit lost zowel de problemen met poortuitputting als DNS-wijzigingen op zonder de overhead van IHttpClientFactory. Als u uw handler wilt kunnen mocken, kunt u deze afzonderlijk registreren.

    Tip

    Als u slechts een beperkt aantal HttpClient exemplaren gebruikt, is dat ook een acceptabele strategie. Wat belangrijk is, is dat ze niet worden gemaakt en verwijderd met elke aanvraag, omdat ze elk een verbindingsgroep bevatten. Het gebruik van meer dan één exemplaar is nodig voor scenario's met meerdere proxy's of om cookiecontainers te scheiden zonder de cookieafhandeling volledig uit te schakelen.

    • Met behulp van IHttpClientFactory kunt u meerdere, verschillend geconfigureerde clients voor verschillende toepassingen hebben. Houd er echter rekening mee dat de door een factory aangemaakte clients bedoeld zijn voor kort gebruik en dat zodra de client is gemaakt, de factory er geen controle meer over heeft.

      De fabriek verzamelt HttpMessageHandler exemplaren, en als de looptijd niet is verlopen, kan een beheerder opnieuw worden gebruikt vanuit de pool wanneer de fabriek een nieuw HttpClient exemplaar creëert. Dit hergebruik voorkomt problemen met socketuitputting.

      Als u de configureerbaarheid wilt die IHttpClientFactory u biedt, raden we u aan de getypeerde clientbenadering te gebruiken.

  • Gebruik in .NET Framework IHttpClientFactory om uw HttpClient exemplaren te beheren. Als u de factory niet gebruikt en in plaats daarvan voor elke aanvraag zelf een nieuw clientexemplaren maakt, kunt u de beschikbare poorten uitputten.

    Tip

    Als uw app cookies vereist, kunt u overwegen automatische cookieafhandeling uit te schakelen of te IHttpClientFactoryvermijden. Het groeperen van de HttpMessageHandler exemplaren resulteert in het delen van CookieContainer objecten. CookieContainer Onverwacht object delen leidt vaak tot onjuiste code.

Voor meer informatie over het beheren van HttpClient levensduur met IHttpClientFactory, zie IHttpClientFactory richtlijnen.

Veerkracht met statische clients

Het is mogelijk om een static of singleton-client te configureren voor het gebruik van een willekeurig aantal resilience pipelines met behulp van het volgende patroon:

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

class MyClass
{
    static HttpClient? s_httpClient;

    MyClass()
    {
        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,
        };

        s_httpClient = new HttpClient(resilienceHandler);
    }
}

De voorgaande code:

  • Is afhankelijk van het NuGet-pakket Microsoft.Extensions.Http.Resilience.
  • Hiermee geeft u een tijdelijke HTTP-fouthandler op, geconfigureerd met pijplijn voor opnieuw proberen die bij elke poging exponentieel vertragingsintervallen van uitstelt.
  • Definieert de levensduur van een gegroepeerde verbinding van vijftien minuten voor de socketHandler.
  • Geeft de socketHandler aan de resilienceHandler met de logica voor opnieuw proberen door.
  • Instantieert een gedeelde HttpClient op basis van de resilienceHandler.

Belangrijk

De Microsoft.Extensions.Http.Resilience-bibliotheek is momenteel gemarkeerd als experimentele en kan in de toekomst veranderen.

Zie ook