Olen aastaid valesti kasutanud HttpClienti, kuid lõpuks tuli õudusunenägu. Minu veebileht oli ebastabiilne ja kliendid olid väga vihased ning lihtsa lahendusega paranes jõudlus oluliselt ja ebastabiilsus kadus.
Samas parandasin oma rakenduse jõudlust efektiivsema pistikupesa kasutamisega.
Mikroteenused võivad olla keeruline probleem. Mida rohkem teenuseid lisatakse ja monoliitsed rakendused lagunevad, seda rohkem on teenuste vahel tekkinud üha rohkem suhtluskanaleid. Suhtlusvõimalusi on palju, kuid HTTP on väga populaarne valik. Kui mikroteenus on ehitatud C# või mõnes muus .NET keeles, siis tõenäoliselt kasutad juba HttpClient'i.
Probleem seisneb
Using lause on C# funktsioon, mis haldab ühekordseid objekte. Kui kasutusplokk on lõpetatud, siis ühekordne objekt (antud juhul HttpClient) jääb ulatusest välja ja kõrvaldatakse. Helista utiliseerimismeetodile ja puhasta kasutatud ressursid. See on väga tüüpiline muster .NET-is, mida kasutame kõiges alates andmebaasist kuni vookirjutajani. Tegelikult kasutab iga objekt, mille väline ressurss tuleb puhastada, seda IDisposable liidest.
Ja sind ei saa süüdistada selles, et tahad seda kasutama panna. Esiteks peetakse seda heaks praktikaks. Tegelikult kasutab Microsofti ametlik dokumentatsioon:
Üldiselt, kui kasutatakse IDisposable objekti, tuleks see deklareerida ja instanteerida using lauses. Teiseks, kogu kood, mida võisid näha...... HttpClienti alguses soovitatakse kasutada using lauseplokki, sealhulgas uusimat dokumentatsiooni saidi enda ASP.NET. Sama on öeldud ka interneti artiklis.
Aga HttpClient on teistsugune. Kuigi see rakendab IDisposable liidest, on see tegelikult jagatud objekt. See tähendab, et kulisside taga on see korduv ja niidikindel. Sa peaksid jagama HttpClienti eksemplari kogu rakenduse eluea jooksul, mitte looma iga täitmise jaoks uut instantsi. HttpClient, vaatame, miks.
Vaata ise
Siin on lihtne programm HttpClienti tutvustamiseks:
See suunatakse aadressile http://aspnetmonsters.comAva 10 päringut ja tee GET, prindime lihtsalt olekukoodi, et teada, et see töötab. Väljund on:
Oota, on veel!
Kõik töö ja kõik on maailmale õige. Aga tegelikult ei ole. Kui võtame netstati tööriista välja ja vaatame selle masina pistikute olekut, näeme:
C:\code\socket>NETSTAT.EXE ... Proto kohalik aadress Välisaadressi olek 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 ASUTATUD ... No see on imelik...... Rakendus on lõpetatud, kuid Azure masinale, mis majutab ASP.NET Monstersi veebilehte, on endiselt palju ühendusi. Nad on seesTIME_WAITstaatus, mis tähendab, et ühendus on ühelt poolt (meie oma) suletud, kuid ootame endiselt, kas veel pakette tuleb, sest need võivad olla võrgus kusagil hilinenud. Siin on TCP/IP staatuse skeem:
Windows jääb selles olekus ühendatuks 240 sekundiks (nagu määratakse [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]). Windowsil on piirang, kui kiiresti saad uue pesa avada, nii et kui ühendusbasseinid otsa saab, võid näha sellist viga:
Ei suuda kaugserveriga ühenduda
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted. Google'ist otsides saad halbu nõuandeid, kuidas ühenduse aegumisi vähendada. Tegelikult, kui serveris HttpClient või sarnaselt konstrueeritud rakendus õigesti töötab, võib ajapiirangute vähendamine põhjustada muid negatiivseid tagajärgi. Me peame mõistma, mida tähendab "õige" ja lahendama selle põhiprobleemi, mitte masintasandi muutujatega nokitsema.
Paranda see
Kui jagame HttpClienti eksemplari, saame vähendada soklite raiskamist, kasutades neid uuesti:
Pane tähele, et kogu rakenduse kohta on meil ainult üks jagatud instants. HttpClient töötab endiselt nagu varem (tegelikult natuke kiiremini soklite taaskasutuse tõttu). Netstat näitab nüüd ainult:
TCP 10.211.55.6:12254 waws-prod-bay-017:http ASUTATUD Tootmisstsenaariumis on mu soklite arv keskmiselt umbes 4000 ja tipphetkel üle 5000, mis sisuliselt surub serveri olemasolevad ressursid kokku ja põhjustab teenuse kokkujooksmise. Pärast muudatuse rakendamist langes kasutatavate pistikupesade arv keskmiselt üle 4000-lt järjepidevalt alla 400-le, tavaliselt umbes 100-le.
See on osa meie jälgimistööriista graafikust, mis näitab, mis juhtub pärast piiratud arvu parandustõendeid paigaldamist valitud mikroteenustele.
See oli dramaatiline. Kui sul on mingisugune koormus, pead meeles pidama neid kahte asja:
Muuda oma HttpClient staatiliseks. Ära viska ega pakenda oma kasutust, välja arvatud juhul, kui otsid konkreetset käitumist (näiteks teenuse ebaõnnestumist). HttpClient
Kokkuvõte
Pistikupesade ammendumise probleem, millega oleme juba kuid võidelnud, on kadunud ja meie klientidel on virtuaalne paraad. Ma ei saa alahinnata, kui ebaselge see viga on. Aastate jooksul oleme harjunud tegelema implementeeritud objektidega, IDisposable'iga ning paljud refaktoreerimistööriistad nagu R# ja CodeRush hoiatavad sind, kui sa seda ei tee. Sellisel juhul on HttpClienti likvideerimine vale lähenemine. HttpClient rakendab IDisposable'i ja julgustab halba käitumist, mis on kahjuks
Originaal:Hüperlingi sisselogimine on nähtav.
|