Ten artykuł jest lustrzanym artykułem tłumaczenia maszynowego, kliknij tutaj, aby przejść do oryginalnego artykułu.

Widok: 6079|Odpowiedź: 4

[Źródło] Nieprawidłowe używanie HttpClient może zepsuć oprogramowanie

[Skopiuj link]
Opublikowano 14.05.2022 17:11:56 | | | |
Od lat używałem HttpClient nieprawidłowo, ale w końcu nadeszła katastrofa. Moja strona była niestabilna, klienci bardzo źli, a prosta poprawka znacznie poprawiła wydajność, a niestabilność została wyeliminowana.



Jednocześnie faktycznie poprawiłem wydajność mojej aplikacji dzięki bardziej efektywnemu wykorzystaniu socketów.

Mikroserwisy mogą być trudnym problemem do rozwiązania. W miarę dodawania kolejnych usług i dekomponowania monolitycznych aplikacji, istnieje coraz więcej ścieżek komunikacyjnych między usługami. Istnieje wiele opcji komunikacyjnych, ale HTTP jest bardzo popularną opcją. Jeśli mikroserwis jest zbudowany w C# lub innym języku .NET, prawdopodobnie już korzystasz z HttpClient.


Problem tkwi

Instrukcja using to funkcja C#, która obsługuje jednorazowe obiekty. Gdy blok użytkownika zostanie ukończony, jednorazowy obiekt (w tym przypadku HttpClient) wychodzi poza zakres i zostaje usunięty. Zadzwoń do metody usuwania i posprzątaj wszelkie używane zasoby. To bardzo typowy wzorzec w .NET, którego używamy we wszystkim – od bazy danych po flow writer. W rzeczywistości każdy obiekt z zewnętrznym zasobem, który musi być czyszczony, korzysta z tego interfejsu IDizposable.

I nie można cię winić, że chcesz to owinąć w używanie. Po pierwsze, uważa się, że jest to dobra praktyka. W rzeczywistości oficjalna dokumentacja Microsoftu używa:


Ogólnie rzecz biorąc, używając obiektu IDisposable, powinien on być zadeklarowany i instancjonowany w instrukcji użyciem.
Po drugie, cały kod, który mogłeś zobaczyć...... Początek HttpClient poinformuje cię, aby użyć bloku instrukcji użycia, w tym najnowszej dokumentacji ASP.NET samej stronie. To samo napisano w artykule w Internecie.

Ale HttpClient jest inny. Chociaż implementuje interfejs IDisposable, jest to w rzeczywistości obiekt współdzielony. Oznacza to, że za kulisami jest to powrotne i bezpieczne dla wątków. Powinieneś udostępniać instancję HttpClient przez cały okres życia aplikacji, zamiast tworzyć nową instancję dla każdego uruchomienia. HttpClient, zobaczmy dlaczego.

Przekonaj się sam

Oto prosty program do demonstracji HttpClient:

To zostanie skierowane do  http://aspnetmonsters.comOtwórz 10 żądań i wykonaj GET, po prostu drukujemy kod statusu, żeby wiedzieć, że działa. Wyniki będą:

Czekaj, jest jeszcze więcej!

Cała praca i wszystko jest odpowiednie dla świata. Z wyjątkiem tego, że tak nie jest. Jeśli wyjmiemy narzędzie netstat i sprawdzimy status gniazda na komputerze, na którym go uruchamiamy, zobaczymy:

C:\code\socket>NETSTAT.EXE
...
  Proto-Lokalny Adres Zagraniczny Stan
  TCP 10.211.55.6:12050 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12051 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12053 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12054 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12055 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12056 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12057 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12058 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12059 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12060 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12061 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12062 waws-prod-bay-017:http TIME_WAIT
  TCP 127.0.0.1:1695 SIMONTIMMS742B:1696 USTANOWIONY
...
To dziwne...... Aplikacja została zamknięta, ale wciąż jest wiele takich połączeń otwartych na maszynie Azure hostującej stronę ASP.NET Monsters. Są w środkuTIME_WAITStatus, co oznacza, że połączenie zostało zamknięte po jednej stronie (naszej), ale wciąż czekamy, czy pojawią się inne pakiety, bo mogły być opóźnione gdzieś w sieci. Oto schemat statusu TCP/IP:



Windows pozostanie połączony w tym stanie przez 240 sekund (ustawione przez ustawienie [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]). Windows ma ograniczenie dotyczące szybkości otwarcia nowego gniazda, więc jeśli skończą się pule połączeń, możesz zobaczyć błąd w tym stylu:

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.
Wyszukanie tego w Google da ci złe rady dotyczące ograniczenia czasu łączności. W rzeczywistości, gdy serwer działa poprawnie na serwerze z HttpClient lub podobnie skonstruowaną aplikacją, ograniczenie limitów może prowadzić do innych negatywnych konsekwencji. Musimy zrozumieć, co oznacza "właściwe" i rozwiązać podstawowy problem, a nie majstrować przy zmiennych na poziomie maszyn.

Napraw to

Jeśli udostępnimy instancję HttpClient, możemy zmniejszyć marnotrawstwo gniazda, używając ich ponownie:

Należy zauważyć, że dla całej aplikacji mamy tylko jedną współdzieloną instancję. HttpClient nadal działa jak wcześniej (właściwie trochę szybciej dzięki ponownemu użyciu gniazda). Netstat teraz pokazuje tylko:

TCP 10.211.55.6:12254 waws-prod-bay-017:http USTANOWIONE
W scenariuszu produkcyjnym średnio liczba gniazd wynosi około 4000, a szczytuje ponad 5000, co skutecznie wyciska dostępne zasoby na serwerze i powoduje awarię usługi. Po wdrożeniu tej zmiany liczba wykorzystywanych gniazd spadła ze średnio ponad 4000 do konsekwentnie poniżej 400, zazwyczaj około 100.

To jest część wykresu z naszego narzędzia monitorującego, który pokazuje, co dzieje się po wdrożeniu ograniczonej liczby dowodów poprawek dla wybranej liczby mikroserwisów.




To było dramatyczne. Jeśli masz jakiekolwiek obciążenie, musisz pamiętać o dwóch kwestiach:

Spraw, by Twój HttpClient był statyczny.
Nie wyrzucaj ani nie pakuj swojego użytku, chyba że wyraźnie szukasz konkretnego zachowania (np. spowodowania awarii usługi). HttpClient


streszczenie

Problem z wyczerpaniem gniazd, z którym zmagaliśmy się od miesięcy, zniknął, a nasi klienci mają wirtualną paradę. Nie mogę lekceważyć, jak nieoczywisty jest ten błąd. Przez lata przyzwyczailiśmy się do pracy z zaimplementowanymi obiektami, IDisposable, a wiele narzędzi refaktoryzujących, takich jak R# i CodeRush, ostrzega, jeśli tego nie robisz. W takim przypadku pozbycie się HttpClient to złe podejście. HttpClient implementuje IDisposable i zachęca do złego zachowania – to niestety

Oryginał:Logowanie do linku jest widoczne.




Poprzedni:ASP.NET Core hostuje modele In-Process i Out-Of-Process w IIS
Następny:ASP.NET Core (XV) używa HttpClient do wysyłania żądań HTTP
 Ziemianin| Opublikowano 14.05.2022 17:25:22 |
TCP TIME_WAIT to zwykła operacja protokołu TCP, co oznacza, że po przekazaniu ostatniego FIN-ACK klient czeka na upływ podwójnego maksymalnego czasu życia (MSL), aby upewnić się, że zdalny TCP otrzyma potwierdzenie żądania zakończenia połączenia. Domyślnie MSL trwa 2 minuty. Możesz pozostać w TIME_WAIT do 4 minut, co nazywa się dwoma MSL.

https://docs.microsoft.com/en-us ... t-from-netstat.html
Opublikowano 14.05.2022 22:35:22 |
Naucz się uczyć
Opublikowano 19.05.2022 09:39:05 |
Wszystko jest po chińsku, ale nie rozumiem tego, gdy jest połączone w zdania
 Ziemianin| Opublikowano 06.11.2023 07:16:05 |
test
Zrzeczenie się:
Całe oprogramowanie, materiały programistyczne lub artykuły publikowane przez Code Farmer Network służą wyłącznie celom edukacyjnym i badawczym; Powyższe treści nie mogą być wykorzystywane do celów komercyjnych ani nielegalnych, w przeciwnym razie użytkownicy ponoszą wszelkie konsekwencje. Informacje na tej stronie pochodzą z Internetu, a spory dotyczące praw autorskich nie mają z nią nic wspólnego. Musisz całkowicie usunąć powyższą zawartość z komputera w ciągu 24 godzin od pobrania. Jeśli spodoba Ci się program, wspieraj oryginalne oprogramowanie, kup rejestrację i korzystaj z lepszych, autentycznych usług. W przypadku naruszenia praw prosimy o kontakt mailowy.

Mail To:help@itsvse.com