När man bygger en applikation med ASP.NET används en instans av HttpClient-klassen för att göra en HTTP-förfrågan. Att använda HttpClient kan verka enkelt. Dock upptäcks vissa potentiella problem inte förrän applikationen är under tung belastning.
Problem relaterade till den ursprungliga HttpClient-klassen som tillhandahålls i .NET:Inloggningen med hyperlänken är synlig.
HttpClient, när IDisposable implementeras, är det inte en föredragen operation att deklarera och instansiera det i using statement, eftersomNär ett HttpClient-objekt släpps gör inte den underliggande socketen detögonblickligensläppa, vilket kan orsaka problem med utmattning av hylsor.
Problemet är egentligen inte HttpClient själv, utan standardkonstruktören av HttpClient, eftersom den skapar en ny faktisk HttpMessageHandler-instans med de "socket exhaustion" och DNS-ändringar som nämnts ovan.
Skapa HttpClient direkt (felaktig användning)
Instansier HttpClient-objektet direkt och lägg till med att garantera anropet till Dispose-metoden, koden är följande:
Anropa gränssnittet 5 gånger, skicka en HTTP-förfrågan med HttpClient och kontrollera nätverksanslutningen med följande kommando:
Du kan se att när HttpClient släpps är anslutningen mellan den lokala datorn och målservernTIME_WAITVid hög samtidighet rapporteras felet enligt följande:
Kan inte ansluta till fjärrservern
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
För frågor kan du också hänvisa til:
Skapa en HttpClinet med IHttpClientFactory (korrekt användning)
Med DI-beroendeinjektion är IHttpClientFactory samma som HttpLinet, som skapas med IHttpClientFactory.
Lägg till tjänsten i Startfilen, koden är följande:
HomeController-kontrollerkoden är följande:
Vi använder också HttpClinet för att skicka 5 förfrågningar via samtalsgränssnittet, och maskinen upprättar endast en anslutning med målservern, och anslutningen återanvänds under förfrågningsprocessen. Som visas nedan:
IHttpClientFactory samlar fabriksskapade HttpMessageHandler-instanser i en pool för att minska resursförbrukningen. När du skapar en ny HttpClient-instans kan du återanvända HttpMessageHandler-instansen i poolen om livslängden inte har löpt ut.
{ "Lifetime": "Singleton", "ServiceType": "System.Net.Http.IHttpClientFactory", "ImplementationType": "Microsoft.Extensions.Http.DefaultHttpClientFactory" }, { "Lifetime": "Singleton", "ServiceType": "System.Net.Http.IHttpMessageHandlerFactory", "ImplementationType": "Microsoft.Extensions.Http.DefaultHttpClientFactory" } IHttpClientFactory är implementerad som standard som DefaultHttpClientFactory, med källkodsadressen:Inloggningen med hyperlänken är synlig.
Genom att använda IHttpClientFactory i en DI-aktiverad applikation kan du undvika:
- Lös problemet med resursutmattning genom att dela HttpMessageHandler-instansen.
- Lös DNS-föråldring genom att periodiskt loopa genom HttpMessageHandler-instanser.
Dessutom finns det andra sätt att lösa ovanstående problem med hjälp av långlivade SocketsHttpHandler-instanser.
- Skapa en instans av SocketsHttpHandler vid appstart och använd den under appens livscykel.
- Konfigurera PooledConnectionLifetime till rätt värde baserat på DNS:s uppdateringstid.
- Skapa en instans av HttpClient med ny HttpClient(handler, disposeHandler: false) vid behov.
Ovanstående metod löser resurshanteringsproblem på ett liknande sätt som IHttpClientFactory.
- SocketsHttpHandler mellan HttpClient-instansernaDelade förbindelser。 Denna delning förhindrar utmattning av hylsorna.
- SocketsHttpHandler loopar anslutningar baserade på PooledConnectionLifetime för att undvika att DNS blir instängd.
För mer användning och konfiguration, vänligen se:
Inloggningen med hyperlänken är synlig.
Inloggningen med hyperlänken är synlig.
|