Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Borravaló
Ez a tartalom egy részlet a "Tárolóalapú .NET-alkalmazásokhoz készült mikroszolgáltatások architektúrája" című eBookból, amely elérhető a .NET Docs oldalon, vagy ingyenesen letölthető PDF-fájlként, amely offline módban is olvasható.
IHttpClientFactory egy szerződés, amelyet a DefaultHttpClientFactory, egy véleményvezérelt gyár valósít meg, és a .NET Core 2.1 óta elérhető. Ez lehetővé teszi HttpClient példányok létrehozását, amelyeket az alkalmazásokban használhat.
A .NET-ben elérhető eredeti HttpClient-osztálysal kapcsolatos problémák
Az eredeti és jól ismert HttpClient osztály könnyen használható, de bizonyos esetekben sok fejlesztő nem használja megfelelően.
Bár ez az osztály implementálja a IDisposable, a using utasításon belüli deklarálás és példányosítás nem javasolt, mert amikor a HttpClient objektumot megsemmisítik, a mögöttes socket nem kerül azonnali felszabadításra, ami socket kimerülés okozta problémát okozhat. A problémával kapcsolatos további információkért tekintse meg a blogbejegyzést, Helytelenül használja a HttpClientet, és ez destabilizálja a szoftverét.
A HttpClient-t ezért egyszeri példányosításra szánják, és az alkalmazás teljes élettartama alatt felhasználják. Ha minden kéréshez létrehoz egy HttpClient osztályt, az kimeríti a nagy terhelés alatt elérhető foglalatok számát. Ez a probléma SocketException hibákat eredményez. A probléma megoldásának lehetséges módjai a HttpClient objektum önálló vagy statikus létrehozásán alapulnak, amint az ebben a Microsoft httpClient-használaticímű cikkében is ismertetjük. Ez jó megoldás lehet olyan rövid élettartamú konzolalkalmazásokhoz vagy hasonlókhoz, amelyek naponta néhányszor futnak.
Egy másik probléma, amelybe a fejlesztők belefutnak, az HttpClient megosztott példányának használata hosszú ideig futó folyamatokban. Ha a HttpClientet singletonként vagy statikus objektumként példányosítják, nem képes kezelni a DNS-változásokat, ahogyan azt a dotnet/runtime GitHub-tárház számú probléma-ben leírja.
A probléma azonban nem önmagában HttpClient, hanem a HttpClient alapértelmezett konstruktorával kapcsolatos, mivel a HttpMessageHandleregy új konkrét példányát hozza létre, amely szoftvercsatornák kimerülési és a FENT említett DNS-módosítási problémákat tartalmaz.
A fent említett problémák megoldása és HttpClient példányok kezelhetővé tétele érdekében a .NET Core 2.1 két megközelítést vezetett be, amelyek közül az egyik IHttpClientFactory. Ez egy felület, amellyel HttpClient-példányokat konfigurálhat és hozhat létre egy alkalmazásban a Függőséginjektálás (DI) használatával. Emellett a Polly-alapú köztes szoftver bővítményeit is biztosítja, hogy kihasználhassa a HttpClient kezelőinek delegálását.
A másik lehetőség a SocketsHttpHandler használata a konfigurált PooledConnectionLifetime. Ez a módszer a hosszú élettartamú, static vagy egyszeri HttpClient példányokra vonatkozik. A különböző stratégiákról további információt a .NET HttpClient-irányelveit ismertető cikkben talál: .
Polly egy átmeneti hibakezelési könyvtár, amely segít a fejlesztőknek növelni az alkalmazásaik rugalmasságát bizonyos előre definiált szabályzatok könnyen olvasható, szálbiztos használatával.
Az IHttpClientFactory használatának előnyei
A IHttpClientFactoryis megvalósító IHttpMessageHandlerFactoryjelenlegi megvalósítása a következő előnyökkel jár:
- Központi helyet biztosít a logikai
HttpClientobjektumok elnevezéséhez és konfigurálásához. Konfigurálhat például egy olyan ügyfelet (szolgáltatásügynököt), amely előre konfigurálva van egy adott mikroszolgáltatás eléréséhez. - Kodifikálja a kimenő köztes szoftver fogalmát a
HttpClientkezelőinek delegálásával és a Polly-alapú köztes szoftver implementálásával, hogy kihasználhassa a Polly rugalmasságra vonatkozó szabályzatait. -
HttpClientmár rendelkezik a kimenő HTTP-kérésekhez összekapcsolható kezelők delegálásának fogalmával. HTTP-ügyfeleket regisztrálhat a gyárban, és egy Polly-kezelővel alkalmazhatja a Polly-szabályzatokat például újrapróbálkozásra, áramkörmegszakításra és más hasonló esetekre. - A HttpMessageHandler élettartamának kezelése az említett problémák elkerülése érdekében, amelyek a
HttpClientélettartamának saját kezeléskor merülhetnek fel.
Borravaló
A DI által injektált HttpClient példányok biztonságosan megsemmisíthetők, mivel a kapcsolódó HttpMessageHandler a gyár kezeli. Az injektált HttpClient példányok a DI szempontjából átmeneti, míg a HttpMessageHandler példányok hatókörűtekinthetők.
HttpMessageHandler példányok saját DI-hatókörrel rendelkeznek, külön az alkalmazás hatókörétől (például ASP.NET bejövő kérelem hatóköreitől). További információért lásd a következőt: HttpClientFactory használata a .NET-ben.
Jegyzet
A IHttpClientFactory (DefaultHttpClientFactory) megvalósítása szorosan kötődik az Microsoft.Extensions.DependencyInjection NuGet-csomag DI-implementációjához. Ha HttpClient-t DI nélkül vagy más DI-implementációkkal kell használnia, fontolja meg static vagy egy példány HttpClient használatát PooledConnectionLifetime beállítással. További információkért tekintse meg a .NET HttpClient irányelveit: .
Az IHttpClientFactory használatának több módja
Az alkalmazásban többféleképpen is használhatja a IHttpClientFactory:
- Alapszintű használat
- Névvel ellátott kliensek használata
- Típusdefiniált ügyfelek használata
- Generált ügyfelek használata
A rövidség kedvéért ez az útmutató bemutatja a IHttpClientFactoryhasználatának legstrukturáltabb módját, amely a típus szerinti kliensek (szolgáltatási ügynök mintázat) használata. Azonban minden lehetőség dokumentálva van, és jelenleg szerepel ebben a cikkben, amely a IHttpClientFactory használatávalfoglalkozik.
Jegyzet
Ha az alkalmazás cookie-kat igényel, érdemes lehet elkerülni a IHttpClientFactory használatát az alkalmazásban. Az ügyfelek kezelésének alternatív módjaiért tekintse meg HTTP-ügyfelekhasználatának irányelveit.
Gépelt ügyfelek használata az IHttpClientFactory használatával
Szóval, mi az a "Típusos ügyfél"? Ez csak egy HttpClient, amely előre konfigurálva van bizonyos használatra. Ez a konfiguráció bizonyos értékeket tartalmazhat, például az alapkiszolgálót, a HTTP-fejléceket vagy az időtúllépéseket.
Az alábbi ábra bemutatja, hogyan alkalmazzák a Typed Clients-et a IHttpClientFactory-val.
8-4. ábra.
IHttpClientFactory használata típusos ügyfélosztályokkal.
A fenti képen a (vezérlő vagy ügyfélkód által használt) ClientService a regisztrált HttpClientáltal létrehozott IHttpClientFactory-et használja. Ez a gyár hozzárendel a HttpMessageHandler-hez egy HttpClient-t egy készletből. A HttpClient a Polly szabályzataival konfigurálható a IHttpClientFactory regisztrálásakor a DI-tárolóban, kiterjesztési módszerrel AddHttpClient.
A fenti struktúra konfigurálásához telepítse az alkalmazásba a IHttpClientFactory NuGet-csomagot, amely tartalmazza a Microsoft.Extensions.Http hozzáadását a AddHttpClientszámára készült IServiceCollection bővítménymetódussal. Ez a bővítménymetódus regisztrálja a belső DefaultHttpClientFactory osztályt, amelyet az interfész IHttpClientFactoryegyetlentonként használ. Átmeneti konfigurációt definiál a HttpMessageHandlerBuilderszámára. A készletből vett üzenetkezelőt (HttpMessageHandler objektumot) a gyárból visszaadott HttpClient használja.
A következő kódrészletben láthatja, hogyan használható AddHttpClient() a HttpClienthasználatához szükséges típusos ügyfelek (szolgáltatásügynökök) regisztrálására.
// Program.cs
//Add http client services at ConfigureServices(IServiceCollection services)
builder.Services.AddHttpClient<ICatalogService, CatalogService>();
builder.Services.AddHttpClient<IBasketService, BasketService>();
builder.Services.AddHttpClient<IOrderingService, OrderingService>();
Ha az ügyfélszolgáltatásokat az előző kódrészletben látható módon regisztrálja, a DefaultClientFactory minden szolgáltatáshoz létrehoz egy szabványos HttpClient. A beírt ügyfél átmenetiként van regisztrálva a DI-tárolóban. Az előző kódban AddHttpClient() a CatalogService , BasketService, OrderingService átmeneti szolgáltatásként regisztrálja, hogy közvetlenül, további regisztrációk nélkül lehessen beszúrni és felhasználni őket.
A regisztrációban a példányspecifikus konfigurációt is hozzáadhatja például az alapcím konfigurálásához, és hozzáadhat néhány rugalmassági szabályzatot, ahogy az alábbi ábrán látható:
builder.Services.AddHttpClient<ICatalogService, CatalogService>(client =>
{
client.BaseAddress = new Uri(builder.Configuration["BaseUrl"]);
})
.AddPolicyHandler(GetRetryPolicy())
.AddPolicyHandler(GetCircuitBreakerPolicy());
Ebben a következő példában a fenti szabályzatok egyikének konfigurációját láthatja:
static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
.WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
}
A Polly használatával kapcsolatos további részleteket a következő cikkbentalálhat.
HttpClient-élettartamok
Minden alkalommal, amikor a HttpClient-től egy IHttpClientFactory objektumot kap, egy új példányt kap vissza. De minden HttpClient egy HttpMessageHandler használ, amelyet a IHttpClientFactory készletezett és újrafelhasznált az erőforrás-felhasználás csökkentése érdekében, feltéve, hogy a HttpMessageHandlerélettartama még nem járt le.
A kezelők készletezése kívánatos, mivel az egyes kezelők általában saját mögöttes HTTP-kapcsolatokat kezelnek; a szükségesnél több kezelő létrehozása kapcsolati késéseket eredményezhet. Egyes kezelők korlátlan ideig nyitva tartják a kapcsolatokat, ami megakadályozhatja, hogy a kezelő reagáljon a DNS-változásokra.
A készlet HttpMessageHandler objektumainak élettartama az a időtartam, amely alatt a készlet egy HttpMessageHandler példánya újra felhasználható. Az alapértelmezett érték két perc, de típusú ügyfélenként felül lehet bírálni. A felülbíráláshoz hívja meg a SetHandlerLifetime()-t az ügyfél létrehozásakor visszaadott IHttpClientBuilder-en, ahogyan az az alábbi kódban látható:
//Set 5 min as the lifetime for the HttpMessageHandler objects in the pool used for the Catalog Typed Client
builder.Services.AddHttpClient<ICatalogService, CatalogService>()
.SetHandlerLifetime(TimeSpan.FromMinutes(5));
Minden típusok szerinti kliensnek lehet saját konfigurált kezelő élettartamának értéke. Állítsa be az élettartamot InfiniteTimeSpan értékre a kezelőfüggvény lejáratának letiltásához.
Az injektált és konfigurált HttpClientet használó gépelt ügyfélosztályok implementálása
Előző lépésként definiálnia kell a típusos ügyfélosztályokat, például a mintakódban szereplő osztályokat, mint a "BasketService", a "CatalogService", vagy az "OrderingService" stb. A típusos ügyfél egy olyan osztály, amely egy HttpClient objektumot fogad el (a konstruktoron keresztül injektálva), és ezt egy távoli HTTP-szolgáltatás meghívására használja. Például:
public class CatalogService : ICatalogService
{
private readonly HttpClient _httpClient;
private readonly string _remoteServiceBaseUrl;
public CatalogService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<Catalog> GetCatalogItems(int page, int take,
int? brand, int? type)
{
var uri = API.Catalog.GetAllCatalogItems(_remoteServiceBaseUrl,
page, take, brand, type);
var responseString = await _httpClient.GetStringAsync(uri);
var catalog = JsonConvert.DeserializeObject<Catalog>(responseString);
return catalog;
}
}
A beírt ügyfelet (CatalogService a példában) a DI (Dependency Injection) aktiválja, ami azt jelenti, hogy a konstruktorban bármilyen regisztrált szolgáltatást elfogadhat a HttpClientmellett.
Egy gépelt kliens tulajdonképpen egy átmeneti objektum, ami azt jelenti, hogy minden alkalommal, amikor szükség van rá, létrejön egy új példány. Új HttpClient példányt kap minden egyes létrehozáskor. A készlet HttpMessageHandler objektumai azonban azok az objektumok, amelyeket több HttpClient példány újra felhasznál.
A gépelt ügyfélosztályok használata
Végül, miután implementálta a típusosan defíniált osztályokat, regisztrálhatja és konfigurálhatja őket AddHttpClient(). Ezt követően bárhol használhatja őket, ahol a DI szolgáltatásokat injektálja, például a Razor oldalkódjában vagy egy MVC webalkalmazás-vezérlőben, amely az alábbi eShopOnContainers-kódban látható:
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{
public class CatalogController : Controller
{
private ICatalogService _catalogSvc;
public CatalogController(ICatalogService catalogSvc) =>
_catalogSvc = catalogSvc;
public async Task<IActionResult> Index(int? BrandFilterApplied,
int? TypesFilterApplied,
int? page,
[FromQuery]string errorMsg)
{
var itemsPage = 10;
var catalog = await _catalogSvc.GetCatalogItems(page ?? 0,
itemsPage,
BrandFilterApplied,
TypesFilterApplied);
//… Additional code
}
}
}
Eddig a pontig a fenti kódrészlet csak a szokásos HTTP-kérések végrehajtására szolgáló példát mutatja. A "varázslat" azonban a következő szakaszokban található, ahol bemutatja, hogy az HttpClient által küldött összes HTTP-kérés hogyan rendelkezhet rugalmas szabályzatokkal, például exponenciális visszakapcsolással, megszakítókkal, hitelesítési jogkivonatokat használó biztonsági funkciókkal vagy bármilyen más egyéni funkcióval. Mindez pedig elvégezhető úgy, hogy szabályzatokat ad hozzá, és kezelőket delegál a regisztrált típus-specifikus ügyfelekhez.
További erőforrások
https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient-guidelines HttpClient-irányelvei a .NET-hez
HttpClientFactory használata a .NET-benhttps://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory
HttpClientFactory használata ASP.NET Corehttps://learn.microsoft.com/aspnet/core/fundamentals/http-requests
HttpClientFactory forráskódja a
dotnet/runtimeGitHub-adattárbanhttps://github.com/dotnet/runtime/tree/release/7.0/src/libraries/Microsoft.Extensions.Http/Polly (.NET rugalmasság és átmeneti hibakezelési kódtár)https://www.pollydocs.org/