Tento článek je zrcadlovým článkem o strojovém překladu, klikněte zde pro přechod na původní článek.

Pohled: 6079|Odpověď: 4

[Zdroj] Nesprávné používání HttpClient může váš software rozbít

[Kopírovat odkaz]
Zveřejněno 14.05.2022 17:11:56 | | | |
HttpClient jsem používal špatně už roky, ale nakonec přišel ten noční můra. Moje webové stránky byly nestabilní a zákazníci velmi naštvaní, a díky jednoduché opravě se výkon výrazně zlepšil a nestabilita byla odstraněna.



Zároveň jsem skutečně zlepšil výkon své aplikace díky efektivnějšímu využití socketů.

Mikroslužby mohou být obtížný problém. Jak přibývá více služeb a monolitické aplikace se rozkládají, obvykle existuje stále více komunikačních cest mezi službami. Existuje mnoho možností komunikace, ale HTTP je velmi oblíbená volba. Pokud je mikroservis postavený v C# nebo jakémkoli .NET jazyce, je pravděpodobné, že už používáte HttpClient.


Problém je

Příkaz using je funkce v C#, která zpracovává jednorázové objekty. Jakmile je blok použití dokončen, jednorázový objekt (v tomto případě HttpClient) je mimo rozsah a zlikvidován. Zavolejte metodu likvidace a ukliďte všechny používané zdroje. Toto je velmi typický vzorec v .NET, který používáme pro vše od databáze až po flow writer. Ve skutečnosti každý objekt s externím zdrojem, který je třeba vyčistit, používá toto IDisposable rozhraní.

A nemůžete být obviněni, že to chcete zabalit do používání. Za prvé, je považováno za dobrou praxi. Oficiální dokumentace Microsoftu ve skutečnosti používá:


Obecně platí, že při použití objektu IDisposable by měl být deklarován a instancován v příkazu using (použití).
Za druhé, všechen kód, který jste možná viděli...... Na začátku HttpClient se objeví příkazový blok používající, včetně nejnovější dokumentace ASP.NET samotném webu. Totéž je uvedeno v článku na internetu.

Ale HttpClient je jiný. Ačkoliv implementuje rozhraní IDisposable, ve skutečnosti jde o sdílený objekt. To znamená, že v zákulisí je to reentrant a bezpečné pro vlákna. Měli byste sdílet instanci HttpClient po celou dobu životnosti aplikace, místo abyste vytvářeli novou instanci pro každé vykonání. HttpClient, podívejme se proč.

Přesvědčte se sami

Tady je jednoduchý program, který demonstruje HttpClient:

Toto bude směrováno na  http://aspnetmonsters.comOtevřete 10 požadavků a uděláte GET, jen vytiskneme stavový kód, takže víme, že to funguje. Výstup bude:

Počkej, je toho víc!

Všechno a všechno je správné pro svět. Jenže není. Pokud vytáhneme nástroj netstat a podíváme se na stav socketu na stroji, který ho běží, uvidíme:

C:\code\socket>NETSTAT.EXE
...
  Proto místní adresa Zahraniční adresa stát
  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 ZALOŽENO
...
No, je to divné...... Aplikace už byla ukončena, ale stále je otevřeno spousta těchto připojení na Azure stroji, který hostuje web ASP.NET Monsters. Jsou vTIME_WAITcož znamená, že spojení bylo na jedné straně (naše) uzavřeno, ale stále čekáme, jestli nepřijdou další pakety, protože mohly být někde v síti zpožděné. Zde je diagram stavu TCP/IP:



Windows zůstanou připojena v tomto stavu po dobu 240 sekund (jak je nastaveno nastavením [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]). Windows má omezení, jak rychle můžete otevřít nový socket, takže pokud vám dojdou pooly připojení, můžete se setkat s chybou jako tato:

Nemohu se připojit k vzdálenému serveru
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Hledání na Googlu vám dá špatné rady, jak snížit časové výpadky připojení. Ve skutečnosti, pokud správně běží na serveru s HttpClientem nebo podobně navrženou aplikací, může snížení časových limitů vést k dalším negativním důsledkům. Musíme pochopit, co znamená "správné" a vyřešit základní problém, ne si hrát s proměnnými na úrovni strojů.

Oprav to

Pokud sdílíme instanci HttpClient, můžeme snížit plýtvání sockety jejich opětovným použitím:

Všimněte si, že pro celou aplikaci máme pouze jednu sdílenou instanci. HttpClient stále funguje jako dřív (vlastně o něco rychleji díky opětovnému použití socketu). Netstat nyní ukazuje jen:

TCP 10.211.55.6:12254 waws-prod-bay-017:http ZALOŽENO
V produkčním scénáři mám průměrný počet socketů kolem 4000 a vrchol přes 5000, což efektivně stlačuje dostupné zdroje na serveru a způsobuje pád služby. Po zavedení této změny počet používaných socketů klesl z průměru přes 4000 na konzistentně méně než 400, obvykle kolem 100.

Toto je část grafu z našeho monitorovacího nástroje, který ukazuje, co se děje poté, co nasadíme omezený počet důkazů oprav na vybraný počet mikroservisů.




Bylo to dramatické. Pokud máte jakoukoli zátěž, musíte mít na paměti tyto dvě věci:

Nastavte svůj HttpClient statický.
Nevyhazujte ani nebalte své použití, pokud výslovně nehledáte konkrétní chování (například způsobení selhání služby). HttpClient


shrnutí

Problém s vyčerpáním socketu, se kterým jsme bojovali měsíce, je pryč a naši zákazníci mají virtuální průvod. Nemohu podcenit, jak nezřejmá je tato chyba. Během let jsme byli zvyklí pracovat s implementovanými objekty, IDisposable a mnoho refaktorovacích nástrojů jako R# a CodeRush vás dokonce varuje, pokud to neuděláte. V tomto případě je likvidace HttpClient špatným přístupem. HttpClient implementuje IDisposable a podporuje špatné chování je bohužel

Původní:Přihlášení k hypertextovému odkazu je viditelné.




Předchozí:ASP.NET Core hostí modely In-Process a Out-Of-Process v IIS
Další:ASP.NET Core (XV) používá HttpClient k odesílání HTTP požadavků
 Pronajímatel| Zveřejněno 14.05.2022 17:25:22 |
TCP TIME_WAIT je běžná operace protokolu TCP, což znamená, že po předání posledního FIN-ACK klient počká, až uplyne dvojnásobná maximální životnost (MSL), aby zajistil, že vzdálený TCP obdrží potvrzení o svém požadavku na ukončení spojení. Ve výchozím nastavení je MSL 2 minuty. V TIME_WAIT můžete zůstat až 4 minuty, což se nazývá dva MSL.

https://docs.microsoft.com/en-us ... t-from-netstat.html
Zveřejněno 14.05.2022 22:35:22 |
Učte se učit
Zveřejněno 19.05.2022 9:39:05 |
Je to všechno čínské, ale nerozumím tomu, když je to propojené do vět
 Pronajímatel| Zveřejněno 06.11.2023 7:16:05 |
test
Zřeknutí se:
Veškerý software, programovací materiály nebo články publikované organizací Code Farmer Network slouží pouze k učení a výzkumu; Výše uvedený obsah nesmí být používán pro komerční ani nelegální účely, jinak nesou všechny důsledky uživatelé. Informace na tomto webu pocházejí z internetu a spory o autorská práva s tímto webem nesouvisí. Musíte výše uvedený obsah ze svého počítače zcela smazat do 24 hodin od stažení. Pokud se vám program líbí, podporujte prosím originální software, kupte si registraci a získejte lepší skutečné služby. Pokud dojde k jakémukoli porušení, kontaktujte nás prosím e-mailem.

Mail To:help@itsvse.com