Acest articol este un articol oglindă al traducerii automate, vă rugăm să faceți clic aici pentru a sări la articolul original.

Vedere: 6079|Răspunde: 4

[Sursă] Folosirea incorectă a HttpClient poate strica software-ul tău

[Copiază linkul]
Postat pe 14.05.2022 17:11:56 | | | |
Am folosit HttpClient greșit ani de zile, dar în cele din urmă a venit coșmarul. Site-ul meu era instabil, iar clienții mei erau foarte supărați, iar cu o soluție simplă, performanța s-a îmbunătățit mult și instabilitatea a fost eliminată.



În același timp, am îmbunătățit performanța aplicației mele cu o utilizare mai eficientă a socket-urilor.

Microserviciile pot fi o problemă dificilă de gestionat. Pe măsură ce sunt adăugate mai multe servicii și aplicațiile monolitice sunt descompuse, tind să existe tot mai multe căi de comunicare între servicii. Există multe opțiuni de comunicare, dar HTTP este o opțiune foarte populară. Dacă microserviciul este construit în C# sau în orice limbaj .NET, cel mai probabil folosești deja HttpClient.


Problema constă

Instrucțiunea using este o caracteristică C# care gestionează obiecte de unică folosință. Odată ce blocul de utilizare este complet, obiectul unic (în acest caz HttpClient) iese din domeniu și este eliminat. Sună la metoda de eliminare și curăță orice resurse folosite. Acesta este un model foarte tipic în .NET pe care îl folosim pentru totul, de la baza de date până la scriitor de flux. De fapt, orice obiect cu o resursă externă care trebuie curățată folosește acea interfață IDisposabilă.

Și nu poți fi învinovățit că vrei să o înfășori în consum. În primul rând, este considerat o practică bună să faci acest lucru. De fapt, documentația oficială Microsoft utilizează:


În general, atunci când se folosește un obiect IDisposabil, acesta ar trebui declarat și instanțiat în instrucțiunea using (using).
În al doilea rând, tot codul pe care l-ai văzut...... Începutul HttpClientului îți va spune să folosești blocul de instrucțiuni using, inclusiv cea mai recentă documentație ASP.NET site-ul propriu-zis. Același lucru se spune și în articolul de pe Internet.

Dar HttpClient este diferit. Deși implementează interfața IDisposabilă, este de fapt un obiect partajat. Asta înseamnă că, în culise, este reentrant și sigur la fir. Ar trebui să partajezi o instanță de HttpClient pe tot parcursul vieții aplicației, în loc să creezi o nouă instanță pentru fiecare execuție. HttpClient, să vedem de ce.

Vezi cu ochii tăi

Iată un program simplu pentru a demonstra HttpClient:

Aceasta va fi îndreptată către  http://aspnetmonsters.comDeschide 10 cereri și face GET, noi doar imprimăm codul de stare, ca să știm că funcționează. Rezultatul va fi:

Stai, mai e ceva!

Toată munca și totul este potrivit pentru lume. Doar că nu este. Dacă scoatem unealta netstat și ne uităm la starea socket-ului mașinii care îl rulează, vom vedea:

C:\code\socket>NETSTAT.EXE
...
  Proto Adresă Locală Stat Adresă Străină
  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 ÎNFIINȚAT
...
Ei bine, e ciudat...... Aplicația a fost închisă, dar încă există o mulțime de astfel de conexiuni deschise către mașina Azure care găzduiește site-ul ASP.NET Monsters. Ei sunt înTIME_WAITStatus, ceea ce înseamnă că conexiunea a fost închisă pe o parte (a noastră), dar încă așteptăm să vedem dacă mai vin și alte pachete pentru că ar fi putut fi întârziate undeva în rețea. Iată o diagramă a stării TCP/IP:



Windows va rămâne conectat în această stare timp de 240 de secunde (așa cum s-a setat prin setarea [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]). Windows are o limită pentru cât de repede poți deschide un socket nou, așa că dacă rămâi fără pool-uri de conexiuni, s-ar putea să vezi o eroare de genul aceasta:

Imposibil de conectat la serverul de la distanță
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Căutarea pe Google îți va da niște sfaturi proaste despre reducerea timpului de conectare. De fapt, atunci când rulează corect pe un server cu HttpClient sau o aplicație construită similar, reducerea timeout-urilor poate duce la alte consecințe negative. Trebuie să înțelegem ce înseamnă "corect" și să rezolvăm problema de bază, nu să ne jucăm cu variabile la nivel de mașină.

Repară-l

Dacă împărțim o instanță de HttpClient, atunci putem reduce risipa de socket prin reutilizarea lor:

Rețineți că pentru întreaga aplicație avem doar o singură instanță partajată. Clientul Http funcționează la fel ca înainte (de fapt puțin mai rapid datorită reutilizării socket-urilor). Netstat arată acum doar:

TCP 10.211.55.6:12254 waws-prod-bay-017:http ÎNFIINȚAT
Într-un scenariu de producție, numărul meu de socket-uri este în medie în jur de 4000 și atinge un vârf de peste 5000, comprimând efectiv resursele disponibile pe server și cauzând blocarea serviciului. După implementarea schimbării, numărul de socluri folosite a scăzut de la o medie de peste 4000 la constant sub 400, de obicei în jur de 100.

Aceasta face parte dintr-un grafic din instrumentul nostru de monitorizare care arată ce se întâmplă după ce implementăm un număr limitat de dovezi de remediere către un număr selectat de microservicii.




A fost dramatic. Dacă ai orice fel de încărcătură, trebuie să ții cont de aceste două lucruri:

Fă-ți clientul Http static.
Nu renunțați sau ambalați utilizarea decât dacă căutați explicit un anumit comportament (cum ar fi să cauzați eșecul serviciului). HttpClient


rezumat

Problema epuizării soclului cu care ne luptam de luni de zile a dispărut, iar clienții noștri au parte de o paradă virtuală. Nu pot subestima cât de neevidentă este această greșeală. De-a lungul anilor, ne-am obișnuit să gestionăm obiecte implementate, IDisposable, iar multe instrumente de refactorizare precum R# și CodeRush chiar te avertizează dacă nu o faci. În acest caz, eliminarea HttpClient este o abordare greșită. HttpClient implementează IDisposable și încurajează comportamentul nepotrivit, ceea ce este nefericit

Original:Autentificarea cu hyperlink este vizibilă.




Precedent:ASP.NET Core găzduiește modelele In-Process și Out-Of-Process în IIS
Următor:ASP.NET Core (XV) folosește HttpClient pentru a trimite cereri HTTP
 Proprietarul| Postat pe 14.05.2022 17:25:22 |
TCP TIME_WAIT este o operație normală a protocolului TCP, ceea ce înseamnă că, după ce ultimul FIN-ACK este depășit, clientul va aștepta să treacă timpul dublu maxim de viață (MSL) pentru a se asigura că TCP-ul de la distanță primește o confirmare a cererii sale de încheiere a conexiunii. În mod implicit, MSL-ul durează 2 minute. Poți sta în TIME_WAIT până la 4 minute, numite două MSL-uri.

https://docs.microsoft.com/en-us ... t-from-netstat.html
Postat pe 14.05.2022 22:35:22 |
Învață să înveți
Postat pe 19.05.2022 09:39:05 |
Totul este chinezesc, dar nu pot înțelege când este legat de propoziții
 Proprietarul| Postat pe 06.11.2023 07:16:05 |
testa
Disclaimer:
Tot software-ul, materialele de programare sau articolele publicate de Code Farmer Network sunt destinate exclusiv scopurilor de învățare și cercetare; Conținutul de mai sus nu va fi folosit în scopuri comerciale sau ilegale, altfel utilizatorii vor suporta toate consecințele. Informațiile de pe acest site provin de pe Internet, iar disputele privind drepturile de autor nu au legătură cu acest site. Trebuie să ștergi complet conținutul de mai sus de pe calculatorul tău în termen de 24 de ore de la descărcare. Dacă îți place programul, te rugăm să susții software-ul autentic, să cumperi înregistrarea și să primești servicii autentice mai bune. Dacă există vreo încălcare, vă rugăm să ne contactați prin e-mail.

Mail To:help@itsvse.com