Podczas budowania aplikacji z ASP.NET, instancja klasy HttpClient jest używana do wykonania żądania HTTP. Korzystanie z HttpClient może wydawać się proste. Jednak niektóre potencjalne problemy nie są zauważane, dopóki aplikacja nie jest obciążona dużym obciążeniem.
Problemy związane z oryginalną klasą HttpClient udostępnioną w .NET:Logowanie do linku jest widoczne.
HttpClient, podczas implementacji IDisposable, deklarowania i instancji w instrukcji using nie jest preferowaną operacją, ponieważPodczas uwalniania obiektu HttpClient, bazowe gniazdo nie jestnatychmiastzwolnić, co może powodować problemy z wyczerpaniem gniazd.
Problemem nie jest sam HttpClient, lecz domyślny konstruktor HttpClient, ponieważ tworzy on nową, faktyczną instancję HttpMessageHandler z problemami "socket exhaustion" i zmianami DNS, o których wspomniano powyżej.
Tworzenie HttpClient bezpośrednio (nieprawidłowe użycie)
Instancjonuj obiekt HttpClient bezpośrednio i dodaj using aby zagwarantować wywołanie do metody Dispose, kod wygląda następująco:
Wywołaj interfejs 5 razy, wyślij żądanie HTTP za pomocą HttpClient i sprawdź połączenie sieciowe za pomocą następującego polecenia:
Widać, że gdy HttpClient zostanie udostępniony, połączenie między komputerem lokalnym a serwerem docelowym jest następująceTIME_WAITW przypadku dużej równoległości błąd będzie raportowany w następujący sposób:
Nie mogę połączyć się z serwerem zdalnym
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
W przypadku pytań możesz również odnieść się do:
Utwórz HttpClinet za pomocą IHttpClientFactory (poprawne użycie)
Przy użyciu wstrzyknięcia zależności DI IHttpClientFactory jest tym samym co HttpLinet, który jest tworzony za pomocą IHttpClientFactory.
Dodaj usługę do pliku Startup, a kod wygląda następująco:
Kod kontrolera HomeController wygląda następująco:
Używamy także HttpClinet do wysyłania 5 żądań przez interfejs wywołań, a maszyna nawiązuje połączenie tylko z docelowym serwerem, a połączenie jest ponownie wykorzystywane podczas procesu żądania. Jak pokazano poniżej:
IHttpClientFactory łączy fabrycznie tworzone instancje HttpMessageHandler do puli, aby zmniejszyć zużycie zasobów. Gdy tworzysz nową instancję HttpClient, możesz ponownie użyć instancji HttpMessageHandler w puli, jeśli jej żywotność nie wygasła.
{ "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 jest domyślnie zaimplementowany jako DefaultHttpClientFactory z adresem kodu źródłowego:Logowanie do linku jest widoczne.
Używając IHttpClientFactory w aplikacji z włączoną DI, możesz uniknąć:
- Rozwiąż problem wyczerpania zasobów, udostępniając instancję HttpMessageHandler.
- Rozwiązuj nieaktualność DNS, okresowo powtarzając instancje HttpMessageHandler.
Ponadto istnieją inne sposoby rozwiązania powyższych problemów, korzystając z długotrwałych instancji SocketsHttpHandler.
- Stwórz instancję SocketsHttpHandler przy starcie aplikacji i używaj jej przez cały cykl życia.
- Konfiguruj PooledConnectionLifetime do odpowiedniej wartości na podstawie czasu odświeżenia DNS.
- Utworzenie instancji HttpClient przy użyciu nowego HttpClient(handler, disposeHandler: false) w razie potrzeby.
Powyższe podejście rozwiązuje problemy zarządzania zasobami podobnie jak IHttpClientFactory.
- SocketsHttpHandler pomiędzy instancjami HttpClientPołączenia współdzielone。 To współdzielenie zapobiega wyczerpaniu gniazd.
- SocketsHttpHandler zapętla połączenia oparte na PooledConnectionLifetime, aby uniknąć stagnacji DNS.
Więcej informacji o zastosowaniu i konfiguracji można znaleźć w:
Logowanie do linku jest widoczne.
Logowanie do linku jest widoczne.
|