Tento článok je zrkadlovým článkom o strojovom preklade, kliknite sem pre prechod na pôvodný článok.

Pohľad: 6079|Odpoveď: 4

[Zdroj] Nesprávne používanie HttpClient môže pokaziť váš softvér

[Kopírovať odkaz]
Zverejnené 14. 5. 2022 17:11:56 | | | |
Už roky používam HttpClient nesprávne, ale nakoniec prišla nočná mora. Moja webová stránka bola nestabilná a moji zákazníci boli veľmi nahnevaní, a jednoduchým riešením sa výkon výrazne zlepšil a nestabilita bola odstránená.



Zároveň som dokonca zlepšil výkon svojej aplikácie efektívnejším využitím socketu.

Mikroslužby môžu byť náročným problémom na riešenie. Ako sa pridáva viac služieb a monolitické aplikácie sa rozkladajú, zvyčajne je medzi službami čoraz viac komunikačných ciest. Existuje mnoho možností komunikácie, ale HTTP je veľmi populárna možnosť. Ak je mikroservis postavený v C# alebo akomkoľvek .NET jazyku, je pravdepodobné, že už používate HttpClient.


Problém je

Príkaz using je funkcia v jazyku C#, ktorá spracováva jednorazové objekty. Keď je použitý blok dokončený, jednorazový objekt (v tomto prípade HttpClient) je mimo rozsahu a zlikvidovaný. Zavolajte metódu likvidácie a vyčistite všetky použité zdroje. Toto je veľmi typický vzor v .NET, ktorý používame na všetko od databázy až po flow writer. V skutočnosti každý objekt s externým zdrojom, ktorý je potrebné vyčistiť, používa toto IDisposable rozhranie.

A nemôžeš byť vinený za to, že to chceš zabaliť do užívania. Po prvé, považuje sa to za dobrú prax. V skutočnosti oficiálna dokumentácia Microsoftu používa:


Vo všeobecnosti, pri použití objektu IDisposable by mal byť deklarovaný a inštanciovaný v príkaze používanie.
Po druhé, všetok kód, ktorý ste možno videli...... Začiatok HttpClient vám povie použiť blok príkazov using vrátane najnovšej dokumentácie ASP.NET samotnej stránke. To isté sa hovorí v článku na internete.

Ale HttpClient je iný. Hoci implementuje rozhranie IDisposable, v skutočnosti ide o zdieľaný objekt. To znamená, že v zákulisí je to reentrant a bezpečné pre thread. Mali by ste zdieľať inštanciu HttpClient počas celej životnosti aplikácie, namiesto vytvárania novej inštancie pre každé spustenie. HttpClient, pozrime sa prečo.

Presvedčte sa sami

Tu je jednoduchý program na demonštráciu HttpClient:

Toto bude smerované na  http://aspnetmonsters.comOtvorte 10 požiadaviek a urobte GET, jednoducho vytlačíme stavový kód, takže vieme, že to funguje. Výstup bude:

Počkaj, je toho viac!

Všetka práca a všetko je správne pre svet. Lenže nie je. Ak vyberieme nástroj netstat a pozrieme sa na stav socketu na stroji, ktorý ho beží, uvidíme:

C:\code\socket>NETSTAT.EXE
...
  Proto miestna adresa Zahraničná adresa štá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ŽENÝ
...
No, je to zvláštne...... Aplikácia už bola ukončená, ale stále je otvorených veľa týchto pripojení na Azure stroj, ktorý hostí webovú stránku ASP.NET Monsters. Sú vTIME_WAITStav, čo znamená, že spojenie bolo uzavreté na jednej strane (na našej), ale stále čakáme, či neprídu ďalšie pakety, pretože mohli byť oneskorené niekde v sieti. Tu je diagram stavu TCP/IP:



Windows zostanú pripojené v tomto stave 240 sekúnd (ako je nastavené nastavením [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]). Windows má limit, ako rýchlo môžete otvoriť nový socket, takže ak vám dôjdu zásoby pripojení, môžete vidieť chybu ako táto:

Nepodarilo sa pripojiť k vzdialenému serveru
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Hľadanie na Google vám dá zlé rady, ako znížiť časové limity pripojenia. V skutočnosti, ak správne bežíte na serveri s HttpClient alebo podobne vytvorenou aplikáciou, zníženie časových limitov môže viesť k ďalším negatívnym dôsledkom. Musíme pochopiť, čo znamená "správne" a vyriešiť základný problém, nie sa hrať s premennými na úrovni stroja.

Oprav to

Ak zdieľame inštanciu HttpClient, môžeme znížiť plytvanie socketmi opätovným použitím:

Upozorňujeme, že pre celú aplikáciu máme len jednu zdieľanú inštanciu. HttpClient stále funguje ako predtým (vlastne o niečo rýchlejšie vďaka opakovanému používaniu socketu). Netstat teraz zobrazuje len:

TCP 10.211.55.6:12254 waws-prod-bay-017:http ZALOŽENÉ
V produkčnom scenári mám priemerný počet socketov okolo 4000 a vrchol nad 5000, čo efektívne stlačí dostupné zdroje na serveri a spôsobí pád služby. Po zavedení tejto zmeny počet používaných pätic klesol z priemeru viac ako 4000 na konzistentne menej ako 400, typicky okolo 100.

Toto je časť grafu z nášho monitorovacieho nástroja, ktorý ukazuje, čo sa deje po nasadení obmedzeného počtu dôkazov opráv na vybraný počet mikroservisov.




Bolo to dramatické. Ak máte akúkoľvek záťaž, musíte mať na pamäti tieto dve veci:

Urobte svoj HttpClient statický.
Nevyhadzujte ani nebalte svoje použitie, pokiaľ výslovne nehľadáte konkrétne správanie (napríklad spôsobenie zlyhania služby). HttpClient


súhrn

Problém s vyčerpaním pätice, s ktorým sme sa trápili už mesiace, je preč a naši zákazníci majú virtuálny sprievod. Nemôžem podceňovať, aká nejasná je táto chyba. Za tie roky sme si zvykli pracovať s implementovanými objektmi, IDisposable a mnohé refaktorovacie nástroje ako R# a CodeRush vás dokonca varujú, ak to neurobíte. V tomto prípade je likvidácia HttpClient nesprávnym prístupom. HttpClient implementuje IDisposable a podporuje zlé správanie, čo je nešťastné

Originál:Prihlásenie na hypertextový odkaz je viditeľné.




Predchádzajúci:ASP.NET Core hostí modely In-Process a Out-Of-Process v IIS
Budúci:ASP.NET Core (XV) používa HttpClient na odosielanie HTTP požiadaviek
 Prenajímateľ| Zverejnené 14. 5. 2022 17:25:22 |
TCP TIME_WAIT je bežná TCP protokolová operácia, čo znamená, že po odoslaní posledného FIN-ACK klient počká na uplynutie dvojnásobnej maximálnej životnosti (MSL), aby sa uistil, že vzdialený TCP dostane potvrdenie o požiadavke na ukončenie spojenia. Štandardne trvá MSL 2 minúty. V TIME_WAIT môžete zostať až 4 minúty, čo sa nazýva dva MSL.

https://docs.microsoft.com/en-us ... t-from-netstat.html
Zverejnené 14. 5. 2022 22:35:22 |
Naučte sa učiť
Zverejnené 19. 5. 2022 9:39:05 |
Všetko je to čínske, ale nerozumiem tomu, keď je to spojené do viet
 Prenajímateľ| Zverejnené 6. 11. 2023 7:16:05 |
test
Vyhlásenie:
Všetok softvér, programovacie materiály alebo články publikované spoločnosťou Code Farmer Network slúžia len na vzdelávacie a výskumné účely; Vyššie uvedený obsah nesmie byť použitý na komerčné alebo nezákonné účely, inak nesú všetky následky používateľmi. Informácie na tejto stránke pochádzajú z internetu a spory o autorské práva s touto stránkou nesúvisia. Musíte úplne vymazať vyššie uvedený obsah zo svojho počítača do 24 hodín od stiahnutia. Ak sa vám program páči, podporte originálny softvér, zakúpte si registráciu a získajte lepšie originálne služby. Ak dôjde k akémukoľvek porušeniu, kontaktujte nás prosím e-mailom.

Mail To:help@itsvse.com