Tämä artikkeli on konekäännöksen peiliartikkeli, klikkaa tästä siirtyäksesi alkuperäiseen artikkeliin.

Näkymä: 6079|Vastaus: 4

[Lähde] HttpClientin väärin käyttö voi rikkoa ohjelmistosi

[Kopioi linkki]
Julkaistu 14.5.2022 17.11.56 | | | |
Olen käyttänyt HttpClientia väärin vuosia, mutta lopulta painajainen tuli. Verkkosivustoni oli epävakaa ja asiakkaani olivat hyvin vihaisia, ja yksinkertaisella korjauksella suorituskyky parani huomattavasti ja epävakaus poistui.



Samaan aikaan paransin sovellukseni suorituskykyä tehokkaammalla socketin käytöllä.

Mikropalvelut voivat olla vaikea ongelma käsitellä. Kun palveluita lisätään ja monoliittisia sovelluksia hajotetaan, palveluiden välillä on yhä enemmän viestintäreittejä. Viestintävaihtoehtoja on monia, mutta HTTP on erittäin suosittu vaihtoehto. Jos mikropalvelu on rakennettu C#:lla tai millä tahansa .NET-kielellä, todennäköisesti käytät jo HttpClientia.


Ongelma on

Käyttämislause on C#-ominaisuus, joka käsittelee kertaluonteisia objekteja. Kun käyttölohko on valmis, kertaluonteinen objekti (tässä tapauksessa HttpClient) poistetaan soveltamisalasta ja hylätään. Kutsu hävitysmenetelmä ja siivoa käytetyt resurssit. Tämä on hyvin tyypillinen kuvio .NETissä, jota käytämme kaikkeen tietokannasta virtauskirjoittajaan. Itse asiassa mikä tahansa objekti, jonka ulkoinen resurssi täytyy puhdistaa, käyttää tätä tunnistettavaa rajapintaa.

Eikä sinua voi syyttää siitä, että haluat kietoa sen käyttämiseen. Ensinnäkin sitä pidetään hyvänä käytäntönä. Itse asiassa Microsoftin virallinen dokumentaatio käytti:


Yleisesti ottaen, kun käytetään IDisposable objectia, se tulisi julistaa ja instansoitua using -lauseessa.
Toiseksi, kaikki koodi, jonka olet ehkä nähnyt...... HttpClientin alussa kehotetaan käyttämään useus-lauseblokkia, mukaan lukien sivuston uusin dokumentaatio ASP.NET. Sama sanotaan myös internet-artikkelissa.

Mutta HttpClient on erilainen. Vaikka se toteuttaa IDisposable-rajapinnan, se on itse asiassa jaettu objekti. Tämä tarkoittaa, että kulissien takana peli on palaava ja lankaturvallista. Sinun tulisi jakaa HttpClient-instanssi koko sovelluksen elinkaaren ajan, sen sijaan että loisit uuden instanssin jokaiselle suoritukselle. HttpClient, katsotaan miksi.

Katso itse

Tässä on yksinkertainen ohjelma HttpClientin esittelyyn:

Tämä ohjataan osoitteeseen  http://aspnetmonsters.comAvaamme 10 pyyntöä ja teemme GET:n, tulostamme vain tilakoodin, jotta tiedämme sen toimivan. Tulos on:

Odota, on vielä lisää!

Kaikki työ ja kaikki on oikein maailmalle. paitsi että se ei ole. Jos otamme netstat-työkalun esiin ja katsomme sitä ajavan koneen socket-tilan, näemme:

C:\code\socket>NETSTAT.EXE
...
  Proto-paikallinen osoite Ulkomainen osoitetila
  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 PERUSTETTU
...
No, se on outoa...... Sovellus on poistettu, mutta Azure-koneeseen, joka isännöi ASP.NET Monstersin verkkosivustoa, on edelleen useita tällaisia yhteyksiä. He ovat mukanaTIME_WAITTila, mikä tarkoittaa, että yhteys on suljettu toiselta puolelta (meidän), mutta odotamme edelleen, tuleeko muita paketteja, koska ne ovat saattaneet olla viivästyneitä verkossa jossain vaiheessa. Tässä on kaavio TCP/IP-tilasta:



Windows pysyy yhteydessä tässä tilassa 240 sekunnin ajan (kuten asetetaan [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]). Windowsilla on rajoitus sille, kuinka nopeasti voit avata uuden socketin, joten jos yhteyspoolit loppuvat, saatat nähdä tällaisen virheen:

Ei pysty yhdistämään etäpalvelimeen
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Googlen haku antaa huonoja neuvoja yhteyden aikakatkaisujen lyhentämiseen. Itse asiassa, kun palvelimella HttpClient tai vastaavasti rakennettu sovellus toimii oikein, aikakatkaisujen lyhentäminen voi johtaa muihin haitallisiin seurauksiin. Meidän täytyy ymmärtää, mitä "oikea" tarkoittaa, ja ratkaista taustalla oleva ongelma, ei säätää koneen tason muuttujia.

Korjaa se

Jos jaamme HttpClient-instansin, voimme vähentää socket-hukkaa käyttämällä niitä uudelleen:

Huomaa, että koko sovelluksessa meillä on vain yksi jaettu instanssi. HttpClient toimii edelleen kuten ennen (itse asiassa hieman nopeampi socketin uudelleenkäytön takia). Netstat näyttää nyt vain:

TCP 10.211.55.6:12254 waws-prod-bay-017:http PERUSTETTU
Tuotantotilanteessa sokettimääräni on keskimäärin noin 4000 ja huipentuu yli 5000:een, mikä käytännössä puristaa palvelimen käytettävissä olevat resurssit ja aiheuttaa palvelun kaatumisen. Muutoksen jälkeen käytössä olevien pistorasioiden määrä laski keskimäärin yli 4000:sta johdonmukaisesti alle 400:aan, tyypillisesti noin 100:aan.

Tämä on osa seurantatyökalumme kaaviota, joka näyttää, mitä tapahtuu sen jälkeen, kun olemme ottaneet käyttöön rajallisen määrän korjaustodisteita valitulle määrälle mikropalveluita.




Se oli dramaattista. Jos sinulla on minkäänlainen kuorma, sinun tulee pitää nämä kaksi asiaa mielessä:

Tee HttpClientistasi staattinen.
Älä hylkää tai paketoi käyttöäsi, ellei sinulla ole nimenomaista haetaan tiettyä käyttäytymistä (kuten palvelun epäonnistumista). HttpClient


yhteenveto

Hylsyjen uupumisongelma, jonka kanssa olemme kamppailleet kuukausia, on poissa, ja asiakkaillamme on virtuaalinen paraati. En voi aliarvioida, kuinka ilmeinen tämä virhe on. Vuosien varrella olemme tottuneet käsittelemään toteutettuja objekteja, IDisposablea, ja monet refaktorointityökalut kuten R# ja CodeRush varoittavat, jos et tee niin. Tässä tapauksessa HttpClientin hävittäminen on väärä lähestymistapa. HttpClient toteuttaa IDisposablen ja kannustaa huonoon käytökseen, mikä on valitettavaa

Alkuperäinen:Hyperlinkin kirjautuminen on näkyvissä.




Edellinen:ASP.NET Core isännöi IIS:n In-Process ja Off-Of-Process -malleja
Seuraava:ASP.NET Core (XV) käyttää HTTP-pyyntöjen lähettämiseen HttpClientia
 Vuokraisäntä| Julkaistu 14.5.2022 17.25.22 |
TCP TIME_WAIT on tavallinen TCP-protokollatoiminto, mikä tarkoittaa, että viimeisen FIN-ACK:n jälkeen asiakas odottaa kaksinkertaisen maksimielinikon (MSL) kulumista varmistaakseen, että etä-TCP saa yhteyden päättämispyynnön kuittauksen. Oletuksena MSL kestää 2 minuuttia. Voit viipyä TIME_WAIT jopa 4 minuuttia, eli kaksi MSL:ää.

https://docs.microsoft.com/en-us ... t-from-netstat.html
Julkaistu 14.5.2022 22.35.22 |
Opettele oppimaan
Julkaistu 19.5.2022 9.39.05 |
Kaikki on kiinaa, mutta en ymmärrä sitä, kun se yhdistetään lauseisiin
 Vuokraisäntä| Julkaistu 6.11.2023 7.16.05 |
testi
Vastuuvapauslauseke:
Kaikki Code Farmer Networkin julkaisemat ohjelmistot, ohjelmamateriaalit tai artikkelit ovat tarkoitettu vain oppimis- ja tutkimustarkoituksiin; Yllä mainittua sisältöä ei saa käyttää kaupallisiin tai laittomiin tarkoituksiin, muuten käyttäjät joutuvat kantamaan kaikki seuraukset. Tämän sivuston tiedot ovat peräisin internetistä, eikä tekijänoikeuskiistat liity tähän sivustoon. Sinun tulee poistaa yllä oleva sisältö kokonaan tietokoneeltasi 24 tunnin kuluessa lataamisesta. Jos pidät ohjelmasta, tue aitoa ohjelmistoa, osta rekisteröityminen ja hanki parempia aitoja palveluita. Jos rikkomuksia ilmenee, ota meihin yhteyttä sähköpostitse.

Mail To:help@itsvse.com