Riktlinjer för att använda HttpClient
Klassen System.Net.Http.HttpClient skickar HTTP-begäranden och tar emot HTTP-svar från en resurs som identifieras av en URI. En HttpClient instans är en samling inställningar som tillämpas på alla begäranden som körs av den instansen, och varje instans använder sin egen anslutningspool, som isolerar dess begäranden från andra. Från och med .NET Core 2.1 SocketsHttpHandler tillhandahåller klassen implementeringen, vilket gör beteendet konsekvent på alla plattformar.
DNS-beteende
HttpClient löser bara DNS-poster när en anslutning skapas. Den spårar inte tidsåtgången (TTL) som angetts av DNS-servern. Om DNS-poster ändras regelbundet, vilket kan inträffa i vissa scenarier, kommer klienten inte att respektera dessa uppdateringar. För att lösa det här problemet kan du begränsa anslutningens livslängd genom att ange PooledConnectionLifetime egenskapen så att DNS-sökningen upprepas när anslutningen ersätts. Ta följande som exempel:
var handler = new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(15) // Recreate every 15 minutes
};
var sharedClient = new HttpClient(handler);
Föregående HttpClient
är konfigurerat för att återanvända anslutningar i 15 minuter. När tidsintervallet som anges av PooledConnectionLifetime har förflutit och anslutningen har slutfört sin senaste associerade begäran (om någon) stängs den här anslutningen. Om det finns begäranden som väntar i kön skapas en ny anslutning efter behov.
Intervallet på 15 minuter valdes godtyckligt för illustrationsändamål. Du bör välja värdet baserat på den förväntade frekvensen för DNS eller andra nätverksändringar.
Poolanslutningar
Anslutningspoolen för en HttpClient är länkad till den underliggande SocketsHttpHandler. När instansen HttpClient tas bort tas alla befintliga anslutningar i poolen bort. Om du senare skickar en begäran till samma server måste en ny anslutning återskapas. Det innebär att det finns en prestandaavgift för att skapa onödiga anslutningar. Dessutom släpps inte TCP-portar omedelbart efter att anslutningen har stängts. (Mer information om detta finns i TCP TIME-WAIT
i RFC 9293.) Om antalet begäranden är hög kan operativsystemets gräns för tillgängliga portar vara uttömd. För att undvika portöverbelastningsproblem rekommenderar vi att HttpClient du återanvänder instanser för så många HTTP-begäranden som möjligt.
Rekommenderad användning
Om du vill sammanfatta rekommenderad HttpClient
användning när det gäller livslängdshantering bör du använda antingen långlivade klienter och ange PooledConnectionLifetime
(.NET Core och .NET 5+) eller kortlivade klienter som skapats av IHttpClientFactory
.
I .NET Core och .NET 5+:
- Använd en
static
eller singleton-instans HttpClient med PooledConnectionLifetime inställt på önskat intervall, till exempel 2 minuter, beroende på förväntade DNS-ändringar. Detta löser både problem med portöverbelastning och DNS-ändringar utan att lägga till omkostnaderna IHttpClientFactoryför . Om du behöver kunna håna hanteraren kan du registrera den separat.
Dricks
Om du bara använder ett begränsat antal HttpClient instanser är det också en acceptabel strategi. Det viktiga är att de inte skapas och tas bort med varje begäran, eftersom de var och en innehåller en anslutningspool. Att använda mer än en instans är nödvändigt för scenarier med flera proxyservrar eller för att separera cookiecontainrar utan att helt inaktivera cookiehantering.
Med kan IHttpClientFactorydu ha flera, olika konfigurerade klienter för olika användningsfall. Tänk dock på att de fabriksskapade klienterna är avsedda att vara kortvariga, och när klienten har skapats har fabriken inte längre kontroll över den.
Fabrikspoolinstanserna HttpMessageHandler , och om dess livslängd inte har upphört att gälla kan en hanterare återanvändas från poolen när fabriken skapar en ny HttpClient instans. Den här återanvändning undviker problem med socketöverbelastning.
Om du vill ha den konfigurerbarhet som finns rekommenderar vi att IHttpClientFactory du använder metoden typed-client.
- Använd en
I .NET Framework använder du IHttpClientFactory för att hantera dina
HttpClient
instanser. Om du inte använder fabriken och i stället skapar en ny klientinstans för varje begäran själv kan du tömma tillgängliga portar.Dricks
Om din app kräver cookies kan du överväga att inaktivera automatisk cookiehantering eller undvika IHttpClientFactory. Poolning av HttpMessageHandler instanser resulterar i delning av CookieContainer objekt. Oväntad CookieContainer objektdelning resulterar ofta i felaktig kod.
Mer information om hur du hanterar HttpClient
livslängden med IHttpClientFactory
finns i IHttpClientFactory
riktlinjer.
Motståndskraft med statiska klienter
Det är möjligt att konfigurera en eller singleton-klient static
att använda valfritt antal resilienspipelines med hjälp av följande mönster:
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);
Koden ovan:
- Förlitar sig på Microsoft.Extensions.Http.Resilience NuGet-paketet.
- Anger en tillfällig HTTP-felhanterare, konfigurerad med en pipeline för återförsök som med varje försök exponentiellt kommer att backoff fördröja intervallen.
- Definierar en poolanslutningstid på 15 minuter för
socketHandler
. socketHandler
Skickar tillresilienceHandler
med logiken för återförsök.- Instansierar en
HttpClient
angivenresilienceHandler
.
Viktigt!
Biblioteket Microsoft.Extensions.Http.Resilience
är för närvarande markerat som experimentellt och kan ändras i framtiden.