Pri gradnji aplikacije z ASP.NET se za HTTP zahtevo uporabi instanca razreda HttpClient. Uporaba HttpClient se morda zdi preprosta. Vendar pa nekaterih morebitnih težav ne opazimo, dokler aplikacija ni pod veliko obremenitvijo.
Težave, povezane z izvirnim razredom HttpClient, ki je bil na voljo v .NET:Prijava do hiperpovezave je vidna.
HttpClient, medtem ko implementira IDisposable, deklariranje in instanciranje v ukazu using ni prednostna operacija, kerKo sprostimo objekt HttpClient, osnovni socket neTakojSprostitev, kar lahko povzroči težave z izčrpanostjo ležišč.
Težava v resnici ni HttpClient sam, temveč v privzetem konstruktorju HttpClienta, saj ustvari novo dejansko instanco HttpMessageHandlerja z zgoraj omenjenimi težavami s "izčrpanostjo socket" in spremembami DNS.
Neposredno ustvarjanje HttpClient (nepravilna uporaba)
Objekt HttpClient ustvari neposredno in dodaj using za zagotovitev klica metode Dispose, koda je naslednja:
Pokliči vmesnik 5-krat, pošlji HTTP zahtevo preko HttpClient in preveri omrežno povezavo z naslednjim ukazom:
Lahko vidite, da je ob izdaji HttpClient povezava med lokalnim računalnikom in ciljnim strežnikomTIME_WAITV primeru visoke sočasnosti bo napaka prijavljena takole:
Ni mogoče vzpostaviti povezave z oddaljenim strežnikom
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Za vprašanja se lahko obrnete tudi na:
Ustvarite HttpClinet z IHttpClientFactory (pravilna raba)
Z uporabo DI injekcije odvisnosti je IHttpClientFactory enak kot HttpLinet, ki je ustvarjen z uporabo IHttpClientFactory.
Dodajte storitev v datoteko Startup, koda je naslednja:
Koda krmilnika HomeController je naslednja:
Uporabljamo tudi HttpClinet za pošiljanje 5 zahtevkov preko vmesnika za klice, pri čemer naprava vzpostavi povezavo le s ciljnim strežnikom, povezava pa se ponovno uporabi med postopkom zahteva. Kot je prikazano spodaj:
IHttpClientFactory združuje tovarniško ustvarjene primerke HttpMessageHandlerja v bazen, da zmanjša porabo virov. Ko ustvarite novo instanco HttpClient, lahko ponovno uporabite instanco HttpMessageHandler v skladu, če življenjska doba še ni potekla.
{ "Lifetime": "Singleton", "ServiceType": "System.Net.Http.IHttpClientFactory", "ImplementationType": "Microsoft.Extensions.Http.DefaultHttpClientFactory" }, { "Lifetime": "Singleton", "ServiceType": "System.Net.Http.IHttpMessageHandlerFactory", "ImplementationType": "Microsoft.Extensions.Http.DefaultHttpClientFactory" } IHttpClientFactory je privzeto implementiran kot DefaultHttpClientFactory z naslovom izvorne kode:Prijava do hiperpovezave je vidna.
Z uporabo IHttpClientFactory v aplikaciji, ki podpira DI, se lahko izognete:
- Rešite problem izčrpanosti virov tako, da delite instanco HttpMessageHandler.
- Odpravite zastarelost DNS tako, da občasno prehajate skozi instance HttpMessageHandler.
Poleg tega obstajajo tudi drugi načini za reševanje zgoraj omenjenih težav z uporabo primerkov SocketsHttpHandler z dolgo življenjsko dobo.
- Ob zagonu aplikacije ustvarite instanco SocketsHttpHandler in jo uporabljajte skozi celoten življenjski cikel aplikacije.
- Nastavite PooledConnectionLifetime na ustrezno vrednost glede na čas osveževanja DNS.
- Po potrebi ustvarite instanco HttpClient z novim HttpClientom (handler, disposeHandler: false).
Zgornji pristop rešuje težave upravljanja virov na podoben način kot IHttpClientFactory.
- SocketsHttpHandler med instancami HttpClientDeljene povezave。 To deljenje preprečuje izčrpanost podnožja.
- SocketsHttpHandler zanka povezav na podlagi PooledConnectionLifetime, da se izogne zastarelosti DNS.
Za več uporabe in konfiguracije si oglejte:
Prijava do hiperpovezave je vidna.
Prijava do hiperpovezave je vidna.
|