Bij het bouwen van een applicatie met ASP.NET wordt een instantie van de HttpClient-klasse gebruikt om een HTTP-verzoek te doen. Het gebruik van HttpClient lijkt misschien eenvoudig. Sommige mogelijke problemen worden echter pas opgemerkt als de applicatie zwaar belast wordt.
Problemen met betrekking tot de originele HttpClient-klasse die in .NET werd geleverd:De hyperlink-login is zichtbaar.
HttpClient, bij het implementeren van IDisposable, is het declareren en instantiëren ervan in de using statement geen voorkeursbewerking, omdatBij het vrijgeven van een HttpClient-object doet de onderliggende socket dat nietonmiddellijkloslaten, wat problemen met socketuitputting kan veroorzaken.
Het probleem ligt niet echt bij HttpClient zelf, maar bij de standaardconstructor van HttpClient, omdat het een nieuwe echte HttpMessageHandler-instantie aanmaakt met de hierboven genoemde "socket exhaustion" en DNS-wijzigingsproblemen.
HttpClient direct aanmaken (onjuiste gebruik)
Instantiat het HttpClient-object direct en voeg toe met behulp om de aanroep van de Dispose-methode te garanderen, de code is als volgt:
Bel de interface vijf keer, stuur een HTTP-verzoek met HttpClient en controleer de netwerkverbinding met het volgende commando:
Je kunt zien dat wanneer de HttpClient wordt vrijgegeven, de verbinding tussen de lokale computer en de doelserver isTIME_WAITIn het geval van hoge gelijktijdigheid wordt de fout als volgt gerapporteerd:
Kan geen verbinding maken met de externe server
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Voor vragen kunt u ook verwijzen naar:
Maak een HttpClinet aan met IHttpClientFactory (correct gebruik)
Met DI-afhankelijkheidsinjectie is IHttpClientFactory hetzelfde als HttpLinet, dat wordt gemaakt met IHttpClientFactory.
Voeg de service toe aan het opstartbestand, de code is als volgt:
De HomeController-controllercode is als volgt:
We gebruiken ook HttpClinet om 5 verzoeken via de oproepinterface te sturen, en de machine legt alleen verbinding met de doelserver, waarna de verbinding tijdens het verzoekproces wordt hergebruikt. Zoals hieronder getoond:
IHttpClientFactory poolt fabrieksgemaakte HttpMessageHandler-instanties in een pool om het resourceverbruik te verminderen. Wanneer je een nieuwe HttpClient-instantie aanmaakt, mag je de HttpMessageHandler-instantie opnieuw gebruiken in de pool als de levensduur nog niet is verlopen.
{ "Lifetime": "Singleton", "ServiceType": "System.Net.Http.IHttpClientFactory", "ImplementatieType": "Microsoft.Extensions.Http.DefaultHttpClientFactory" }, { "Lifetime": "Singleton", "ServiceType": "System.Net.Http.IHttpMessageHandlerFactory", "ImplementatieType": "Microsoft.Extensions.Http.DefaultHttpClientFactory" } IHttpClientFactory is standaard geïmplementeerd als DefaultHttpClientFactory, met het broncodeadres:De hyperlink-login is zichtbaar.
Door IHttpClientFactory te gebruiken in een DI-geschikte applicatie, kun je het volgende vermijden:
- Los het probleem van resource-uitputting op door de HttpMessageHandler-instantie te delen.
- Los DNS-veroudering op door periodiek door HttpMessageHandler-instanties te lopen.
Daarnaast zijn er andere manieren om bovenstaande problemen op te lossen met behulp van SocketsHttpHandler-instanties met een lange levensduur.
- Maak een instantie van SocketsHttpHandler aan bij het opstarten van de app en gebruik deze gedurende de hele levenscyclus van de app.
- Configureer PooledConnectionLifetime op de juiste waarde op basis van de DNS-verversingstijd.
- Maak een instantie van HttpClient aan met de nieuwe HttpClient(handler, disposeHandler: false) indien nodig.
De bovenstaande aanpak lost resource managementproblemen op een vergelijkbare manier op als IHttpClientFactory.
- SocketsHttpHandler tussen de HttpClient-instantiesGedeelde verbindingen。 Dit delen voorkomt dat de socket wordt uitputt.
- SocketsHttpHandler sluit verbindingen op basis van PooledConnectionLifetime om veroudering van DNS te voorkomen.
Voor meer gebruik en configuratie, zie alstublieft:
De hyperlink-login is zichtbaar.
De hyperlink-login is zichtbaar.
|