Évek óta rosszul használom a HttpClient-t, de végül eljött a rémálom. A weboldalam instabil volt, az ügyfeleim nagyon dühösek voltak, és egy egyszerű javítással jelentősen javult a teljesítmény, és az instabilitás megszűnt.
Ugyanakkor hatékonyabb aljzat használatával javítottam az alkalmazásom teljesítményét.
A mikroszolgáltatások nehéz problémát jelenthetnek. Ahogy egyre több szolgáltatás kerül hozzá és monolitikus alkalmazások lebontakoznak, egyre több kommunikációs útvonal alakul ki a szolgáltatások között. Számos kommunikációs lehetőség van, de a HTTP nagyon népszerű. Ha a mikroszolgáltatás C#-ban vagy bármilyen .NET nyelven van beépítve, akkor valószínűleg már használod a HttpClient-et.
A probléma rejlik
A using utasítás egy C# funkció, amely egyszeri objektumokat kezel. Amint a használati blokk elkészült, akkor az egyszeri objektum (jelen esetben a HttpClient) kikerül a hatókörből, és eltűnik. Hívd fel az elhelyezési módszert, és takarítsd ki a használt erőforrásokat. Ez egy nagyon tipikus minta a .NET-ben, amit mindennél használunk az adatbázistól a folyamatíróig. Valójában bármely objektum, amelynek külső erőforrása tisztítani kell, használja ezt az IDisposable interfészt.
És nem hibáztathatod azért, hogy be akarod csomagolni a használatba. Először is, ezt jó gyakorlatnak tartják. Valójában a Microsoft hivatalos dokumentációja a következőket használja:
Általánosságban, amikor IDisposable objektumot használunk, azt a using utasításban kell deklarálni és instanciálni. Másodszor, az összes kódot, amit esetleg láttál...... A HttpClient elején azt mondja, hogy használd a using utasításblokkot, beleértve a legfrissebb dokumentációt ASP.NET az oldalról. Ugyanezt mondják az internetes cikkben is.
De a HttpClient más. Bár megvalósítja az IDisposable interfészt, valójában egy megosztott objektum. Ez azt jelenti, hogy a háttérben visszatérő és szálas biztonságban van. A HttpClient példányát az alkalmazás élettartama alatt kell megosztani, nem pedig minden végrehajtáshoz új példányt hozni létre. A HttpClient, nézzük meg, miért.
Nézd meg magad
Íme egy egyszerű program a HttpClient bemutatására:
Ezt a címet a következőkre irányítjuk http://aspnetmonsters.comNyitunk ki 10 kérést, és GET-et csinálunk, mi csak kinyomtatjuk az állapotkódot, így tudjuk, hogy működik. A kimenet a következő lesz:
Várj, van még több!
Minden munka és minden rendben van a világnak. Csakhogy nem az. Ha előveszjük a netstat eszközt, és megnézzük a futtató gép socket állapotát, akkor látjuk:
C:\code\socket>NETSTAT.EXE ... Proto helyi cím Külföldi címállapot 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 ALAPÍTVA ... Hát, furcsa...... Az alkalmazás kikapcsolt, de még mindig sok ilyen kapcsolat van nyitva az Azure géphez, amely a ASP.NET Monsters weboldalt üzemelteti. Ők beléptekTIME_WAITÁllapot, ami azt jelenti, hogy az egyik oldalon (a miénk) lezárták a kapcsolatot, de még várjuk, hogy érkezik-e még csomagok, mert esetleg késleltették a hálózaton. Íme egy diagram a TCP/IP státuszról:
A Windows ebben az állapotban 240 másodpercig marad csatlakoztatva (ahogy a [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]-val beállítva). A Windowsnak van egy korlátja arra, hogy milyen gyorsan tudsz új socketet nyitni, így ha elfogynak a kapcsolati poolok, akkor ilyen hibát láthatsz:
Nem tudok csatlakozni a távoli szerverhez
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted. Ha rákeressz a Google-ban, rossz tanácsokat adsz a kapcsolati időkorlátok csökkentésére. Valójában, ha egy szerveren HttpClient-rel vagy hasonlóan felépített alkalmazással helyesen fut, az időtúllépések csökkentése más káros következményekkel járhat. Meg kell értenünk, mit jelent a "helyes" szó, és meg kell oldanunk az alapvető problémát, nem pedig gépi szintű változókat babrálnunk.
Javítsd meg
Ha megosztunk egy HttpClient példányt, akkor csökkenthetjük a socket-pazarlást azzal, hogy újrahasznosítjuk őket:
Fontos megjegyezni, hogy az egész alkalmazáshoz csak egy közös példányunk van. A HttpClient továbbra is úgy működik, mint korábban (valójában egy kicsit gyorsabb a socket újrahasználat miatt). A Netstat most már csak a következőket mutatja:
TCP 10.211.55.6:12254 waws-prod-bay-017:http MEGALAPÍTVA Egy termelési helyzetben a socket számom átlagosan 4000 körül van, és csúcspontja 5000 fölé ér, ami gyakorlatilag összeszorítja a szerver rendelkezésre álló erőforrásait, ami a szolgáltatás összeomlásához vezet. A változtatás bevezetése után a használt foglalatok száma átlagosan 4000 feletti voltról következetesen kevesebb mint 400-ra, általában körülbelül 100-ra.
Ez egy táblázat része a monitorozó eszközünknek, amely megmutatja, mi történik, miután korlátozott számú javítási bizonyítást telepítünk kiválasztott mikroszolgáltatásokba.
Ez drámai volt. Ha bármilyen terhelésed van, ezeket a két dolgot kell szem előtt tartanod:
Tedd statikus a HttpClient-edet. Ne dobd el vagy csomagold a használatodat, hacsak nem kifejezetten konkrét viselkedést keresel (például a szolgáltatás meghibásodását). HttpClient
összefoglalás
A konnektor kimerülési problémá, amivel hónapok óta küzdünk, elmúlt, és ügyfeleink virtuális felvonulást tartanak. Nem becsülhetem alá, mennyire nyilvánvaló ez a hiba. Az évek során hozzászoktunk a megvalósított objektumokhoz, az IDisposable-hez, és sok refaktoráló eszköz, mint az R# és a CodeRush, figyelmeztet, ha nem teszed meg. Ebben az esetben a HttpClient megszüntetése rossz megközelítés. A HttpClient megvalósítja az IDisposable-t, és ösztönzi a rossz viselkedést, ami sajnálatos
Eredeti:A hiperlink bejelentkezés látható.
|