Denne artikel er en spejling af maskinoversættelse, klik venligst her for at springe til den oprindelige artikel.

Udsigt: 6079|Svar: 4

[Kilde] Forkert brug af HttpClient kan ødelægge din software

[Kopier link]
Opslået på 14/05/2022 17.11.56 | | | |
Jeg har brugt HttpClient forkert i årevis, men til sidst kom mareridtet. Min hjemmeside var ustabil, og mine kunder var meget vrede, og med en simpel løsning blev ydeevnen markant forbedret, og ustabiliteten blev elimineret.



Samtidig forbedrede jeg faktisk ydeevnen i min applikation med mere effektiv socket-brug.

Mikroservices kan være et vanskeligt problem at håndtere. Efterhånden som flere tjenester tilføjes og monolitiske applikationer nedbrydes, har der en tendens til at være flere og flere kommunikationsveje mellem tjenesterne. Der findes mange kommunikationsmuligheder, men HTTP er en meget populær mulighed. Hvis mikroservicen er bygget i C# eller et hvilket som helst .NET-sprog, er der stor sandsynlighed for, at du allerede bruger HttpClient.


Problemet ligger

Usætningen using er en C#-funktion, der håndterer engangsobjekter. Når brugsblokken er færdig, er engangsobjektet (i dette tilfælde HttpClient) uden for omfanget og bortskaffet. Kald bortskaffelsesmetoden og ryd op i eventuelle ressourcer, der bruges. Dette er et meget typisk mønster i .NET, som vi bruger til alt fra databasen til flow-skriveren. Faktisk bruger ethvert objekt med en ekstern ressource, der skal renses, det IDISPOSABLE interface.

Og man kan ikke bebrejdes for at ville pakke det ind i brug. For det første anses det for at være en god praksis at gøre det. Faktisk bruger Microsofts officielle dokumentation:


Generelt, når man bruger et IDisposable-objekt, bør det erklæres og instansieres i using statement.
For det andet, al den kode, du måske har set...... Begyndelsen af HttpClient vil fortælle dig, at du skal bruge using statement-blokken, inklusive den nyeste dokumentation ASP.NET selve siden. Det samme siges i artiklen på internettet.

Men HttpClient er anderledes. Selvom den implementerer det IDISPOSABLE interface, er det faktisk et delt objekt. Det betyder, at det bag kulisserne er reentrant og trådsikkert. Du bør dele en HttpClient-instans gennem hele applikationens levetid i stedet for at oprette en ny instans for hver eksekvering. HttpClient, lad os se hvorfor.

Se selv

Her er et simpelt program til at demonstrere HttpClient:

Dette vil blive rettet til  http://aspnetmonsters.comÅbn 10 forespørgsler og lav GET, vi printer bare statuskoden, så vi ved, det virker. Outputtet vil være:

Vent, der er mere!

Alt arbejde og alt er rigtigt for verden. Men det er det ikke. Hvis vi trækker netstat-værktøjet frem og ser på socket-status på maskinen, der kører det, vil vi se:

C:\code\socket>NETSTAT.EXE
...
  Proto lokal adresse udenlandsk adresse stat
  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 ETABLERET
...
Nå, det er mærkeligt...... Applikationen er afsluttet, men der er stadig en masse af disse forbindelser åbne til Azure-maskinen, der hoster ASP.NET Monsters-hjemmesiden. De er iTIME_WAITstatus, hvilket betyder, at forbindelsen er blevet lukket på den ene side (vores), men vi venter stadig på at se, om der kommer andre pakker ind, fordi de måske er blevet forsinket på netværket et sted. Her er et diagram over TCP/IP-status:



Windows forbliver forbundet i denne tilstand i 240 sekunder (som sat ved at sætte [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]). Windows har en grænse for, hvor hurtigt du kan åbne en ny socket, så hvis du løber tør for forbindelsespools, kan du opleve en fejl som denne:

Kan ikke oprette forbindelse til den eksterne server
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
At søge efter det på Google vil give dig dårlige råd om at reducere forbindelsestid. Faktisk kan reduktion af timeouts, når man kører korrekt på en server med HttpClient eller en lignende applikation, føre til andre negative konsekvenser. Vi skal forstå, hvad "rigtigt" betyder, og løse det underliggende problem, ikke pille ved maskinniveau-variabler.

Fiks det

Hvis vi deler en instans af HttpClient, kan vi reducere socket-spild ved at genbruge dem:

Bemærk, at vi kun har én delt instans for hele applikationen. HttpClient virker stadig som før (faktisk lidt hurtigere på grund af genbrug af socket). Netstat viser nu kun:

TCP 10.211.55.6:12254 waws-prod-bay-017:http ETABLERET
I et produktionsscenarie ligger mit socket-antal i gennemsnit omkring 4000 og topper over 5000, hvilket effektivt presser de tilgængelige ressourcer på serveren og får tjenesten til at crashe. Efter implementeringen af ændringen faldt antallet af anvendte sokler fra et gennemsnit på over 4000 til konsekvent under 400, typisk omkring 100.

Dette er en del af et diagram fra vores overvågningsværktøj, der viser, hvad der sker, efter vi har implementeret et begrænset antal fix proofs til et udvalgt antal mikrotjenester.




Det var dramatisk. Hvis du har en form for belastning, skal du huske disse to ting:

Gør din HttpClient statisk.
Kasser eller pakk ikke dit forbrug, medmindre du eksplicit leder efter en specifik adfærd (som at få din service til at fejle). HttpClient


resumé

Problemet med udmattelse af stikkontakter, som vi har kæmpet med i flere måneder, er væk, og vores kunder har en virtuel parade. Jeg kan ikke undervurdere, hvor uåbenlys denne fejl er. Gennem årene er vi blevet vant til at håndtere implementerede objekter, IDisposable, og mange refaktoreringsværktøjer som R# og CodeRush advarer dig faktisk, hvis du ikke gør det. I dette tilfælde er det forkert at bortskaffe HttpClient. HttpClient implementerer IDisposable og opfordrer til dårlig adfærd er uheldigt

Oprindelig:Hyperlink-login er synlig.




Tidligere:ASP.NET Core huser In-Process og Out-of-Process modellerne i IIS
Næste:ASP.NET Core (XV) bruger HttpClient til at sende HTTP-forespørgsler
 Udlejer| Opslået på 14/05/2022 17.25.22 |
TCP TIME_WAIT er en normal TCP-protokoloperation, hvilket betyder, at efter den sidste FIN-ACK er overgået, vil klienten vente på, at den dobbelte maksimale levetid (MSL) passerer for at sikre, at den fjerne TCP modtager en bekræftelse af sin anmodning om forbindelsesafslutning. Som standard varer MSL 2 minutter. Du kan blive i TIME_WAIT i op til 4 minutter, kendt som to MSL'er.

https://docs.microsoft.com/en-us ... t-from-netstat.html
Opslået på 14/05/2022 22.35.22 |
Lær at lære
Opslået på 19/05/2022 09.39.05 |
Det er alt sammen kinesisk, men jeg kan ikke forstå det, når det er forbundet til sætninger
 Udlejer| Opslået på 06/11/2023 07.16.05 |
test
Ansvarsfraskrivelse:
Al software, programmeringsmaterialer eller artikler udgivet af Code Farmer Network er kun til lærings- og forskningsformål; Ovenstående indhold må ikke bruges til kommercielle eller ulovlige formål, ellers skal brugerne bære alle konsekvenser. Oplysningerne på dette site kommer fra internettet, og ophavsretstvister har intet med dette site at gøre. Du skal slette ovenstående indhold fuldstændigt fra din computer inden for 24 timer efter download. Hvis du kan lide programmet, så understøt venligst ægte software, køb registrering og få bedre ægte tjenester. Hvis der er nogen overtrædelse, bedes du kontakte os via e-mail.

Mail To:help@itsvse.com