Beim Erstellen einer Anwendung mit ASP.NET wird eine Instanz der HttpClient-Klasse verwendet, um eine HTTP-Anfrage zu stellen. Die Nutzung von HttpClient mag einfach erscheinen. Einige potenzielle Probleme werden jedoch erst bemerkt, wenn die Anwendung stark belastet ist.
Probleme im Zusammenhang mit der ursprünglichen HttpClient-Klasse in .NET:Der Hyperlink-Login ist sichtbar.
HttpClient ist bei der Implementierung von IDisposable keine bevorzugte Operation, es in der Using-Anweisung zu deklarieren und zu instanziieren, daBeim Freigeben eines HttpClient-Objekts tut der zugrundeliegende Socket dies nichtaugenblicklichloslassen, was Probleme mit der Erschöpfung der Fassung verursachen kann.
Das Problem liegt eigentlich nicht bei HttpClient selbst, sondern am Standard-Konstruktor von HttpClient, da es eine neue tatsächliche HttpMessageHandler-Instanz mit den oben genannten "Socket-Erschöpfung"- und DNS-Change-Problemen erstellt.
Direkte Erstellung von HttpClient (falsche Nutzung)
Instanziiert man das HttpClient-Objekt direkt und fügt man mit zur Garantie des Aufrufs der Dispose-Methode einen Aufruf hinzu, sieht der Code wie folgt aus:
Rufen Sie die Schnittstelle fünfmal an, senden Sie eine HTTP-Anfrage über HttpClient und überprüfen Sie die Netzwerkverbindung mit folgendem Befehl:
Man sieht, dass bei der Freigabe des HttpClient die Verbindung zwischen dem lokalen Computer und dem ZielserverTIME_WAITBei hoher Nebenläufigkeit wird der Fehler wie folgt gemeldet:
Keine Verbindung zum entfernten Server möglich
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Für Fragen können Sie auch nachsehen:
Erstellen Sie ein HttpClinet mit IHttpClientFactory (korrekte Verwendung)
Mit DI-Abhängigkeitsinjektion ist IHttpClientFactory dasselbe wie HttpLinet, das mit IHttpClientFactory erstellt wird.
Füge den Dienst der Startdatei hinzu, der Code lautet wie folgt:
Der HomeController-Controller-Code ist wie folgt:
Wir verwenden außerdem HttpClinet, um 5 Anfragen über die Anrufschnittstelle zu senden, und die Maschine stellt nur eine Verbindung mit dem Zielserver her, und die Verbindung wird während des Anfrageprozesses wiederverwendet. Wie unten gezeigt:
IHttpClientFactory sammelt fabrikerstellte HttpMessageHandler-Instanzen in einen Pool, um den Ressourcenverbrauch zu reduzieren. Wenn Sie eine neue HttpClient-Instanz erstellen, können Sie die HttpMessageHandler-Instanz im Pool wiederverwenden, sofern die Lebensdauer nicht abgelaufen ist.
{ "Lebenszeit": "Singleton", "ServiceType": "System.Net.Http.IHttpClientFactory", "ImplementationType": "Microsoft.Extensions.Http.DefaultHttpClientFactory" }, { "Lebenszeit": "Singleton", "ServiceType": "System.Net.Http.IHttpMessageHandlerFactory", "ImplementationType": "Microsoft.Extensions.Http.DefaultHttpClientFactory" } IHttpClientFactory ist standardmäßig als DefaultHttpClientFactory implementiert, mit der Quellcodeadresse:Der Hyperlink-Login ist sichtbar.
Indem Sie IHttpClientFactory in einer DI-fähigen Anwendung verwenden, können Sie:
- Lösen Sie das Problem der Ressourcenerschöpfung, indem Sie die HttpMessageHandler-Instanz teilen.
- Lösen Sie die DNS-Stagnation, indem Sie regelmäßig durch HttpMessageHandler-Instanzen laufen.
Darüber hinaus gibt es weitere Möglichkeiten, die oben genannten Probleme mit langlebigen SocketsHttpHandler-Instanzen zu lösen.
- Erstelle beim App-Start eine Instanz von SocketsHttpHandler und nutze sie während des gesamten Lebenszyklus der App.
- Konfigurieren Sie PooledConnectionLifetime auf den entsprechenden Wert basierend auf der DNS-Aktualisierungszeit.
- Erstellen Sie eine Instanz von HttpClient mit dem neuen HttpClient(handler, disposeHandler: false) bei Bedarf.
Der obige Ansatz löst Ressourcenmanagementprobleme ähnlich wie IHttpClientFactory.
- SocketsHttpHandler zwischen den HttpClient-InstanzenGemeinsame Verbindungen。 Dieses Teilen verhindert die Erschöpfung der Sockel.
- SocketsHttpHandler schließt Verbindungen basierend auf PooledConnectionLifetime, um DNS-Stagnation zu vermeiden.
Für weitere Nutzung und Konfiguration siehe bitte:
Der Hyperlink-Login ist sichtbar.
Der Hyperlink-Login ist sichtbar.
|