Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Saran
Konten ini adalah kutipan dari eBook, Arsitektur Layanan Mikro .NET untuk Aplikasi .NET Kontainer, tersedia di .NET Docs atau sebagai PDF gratis yang dapat diunduh yang dapat dibaca secara offline.
IHttpClientFactory adalah kontrak yang diimplementasikan oleh DefaultHttpClientFactory, sebuah pabrik yang memiliki opini kuat, tersedia sejak .NET Core 2.1, untuk membuat instance HttpClient yang akan digunakan dalam aplikasi Anda.
Masalah dengan kelas HttpClient asli yang tersedia di .NET
Kelas HttpClient asli dan terkenal dapat dengan mudah digunakan, tetapi dalam beberapa kasus, kelas tersebut tidak digunakan dengan benar oleh banyak pengembang.
Meskipun kelas ini mengimplementasikan IDisposable, mendeklarasikan dan membuat instansnya dalam pernyataan using sebaiknya dihindari karena ketika objek HttpClient dibuang, soket utama tidak segera dilepaskan, yang dapat menyebabkan masalah kelelahan soket . Untuk informasi selengkapnya tentang masalah ini, lihat posting blog Anda menggunakan HttpClient salah dan itu merusak perangkat lunak Anda.
Oleh karena itu, HttpClient dimaksudkan untuk diinstansiasi sekali dan digunakan kembali selama masa pakai aplikasi. Membuat instans kelas HttpClient untuk setiap permintaan akan menghabiskan jumlah soket yang tersedia di bawah beban berat. Masalah tersebut akan mengakibatkan kesalahan SocketException. Kemungkinan pendekatan untuk menyelesaikan masalah tersebut didasarkan pada pembuatan objek HttpClient sebagai singleton atau statis, seperti yang dijelaskan dalam artikel microsoft ini tentang penggunaan HttpClient. Ini bisa menjadi solusi yang baik untuk aplikasi konsol berumur pendek atau sejenisnya, yang berjalan beberapa kali sehari.
Masalah lain yang dihadapi oleh pengembang adalah ketika menggunakan instance yang digunakan bersama HttpClient dalam proses yang berjalan lama. Dalam situasi di mana HttpClient dibuat sebagai singleton atau objek statis, HttpClient gagal menangani perubahan DNS seperti yang dijelaskan dalam masalah pada repositori dotnet/runtime di GitHub.
Namun, masalahnya tidak benar-benar HttpClient per detik, tetapi dengan konstruktor default untuk HttpClient, karena membuat instans konkret baru HttpMessageHandler, yang merupakan konstruktor kelelahan soket dan masalah perubahan DNS yang disebutkan di atas.
Untuk mengatasi masalah yang disebutkan di atas dan membuat instans HttpClient dapat dikelola, .NET Core 2.1 memperkenalkan dua pendekatan, salah satunya adalah IHttpClientFactory. Ini adalah antarmuka yang digunakan untuk mengonfigurasi dan membuat instans HttpClient di aplikasi melalui Injeksi Dependensi (DI). Ini juga menyediakan ekstensi untuk middleware berbasis Polly untuk memanfaatkan pendelegasian handler di HttpClient.
Alternatifnya adalah menggunakan SocketsHttpHandler yang dikonfigurasi dengan PooledConnectionLifetime. Pendekatan ini diterapkan pada instans berumur panjang, static, atau singleton HttpClient. Untuk mempelajari selengkapnya tentang strategi yang berbeda, lihat panduan HttpClient untuk .NET.
Polly adalah pustaka penanganan kesalahan singkat yang membantu pengembang menambahkan ketahanan pada aplikasi mereka, dengan menggunakan beberapa kebijakan yang telah ditentukan sebelumnya dengan cara yang mudah dibaca dan aman untuk digunakan dengan utas.
Manfaat menggunakan IHttpClientFactory
Implementasi IHttpClientFactorysaat ini , yang juga mengimplementasikan IHttpMessageHandlerFactory, menawarkan manfaat berikut:
- Menyediakan lokasi pusat untuk penamaan dan konfigurasi objek
HttpClientlogis. Misalnya, Anda dapat mengonfigurasi klien (Agen Layanan) yang telah dikonfigurasi sebelumnya untuk mengakses layanan mikro tertentu. - Menetapkan konsep middleware yang keluar dengan mendelegasikan handler dalam
HttpClientdan menerapkan middleware berbasis Polly untuk memanfaatkan kebijakan Polly guna meningkatkan ketahanan. -
HttpClientsudah memiliki konsep mendelegasikan handler yang bisa dihubungkan bersama untuk permintaan HTTP keluar. Anda dapat mendaftarkan klien HTTP ke dalam sistem dan menggunakan handler Polly untuk menerapkan kebijakan Polly seperti Retry, CircuitBreakers, dan lain-lain. - Kelola masa pakai HttpMessageHandler untuk menghindari masalah/masalah yang disebutkan yang dapat terjadi saat mengelola masa pakai
HttpClientsendiri.
Saran
Instans HttpClient yang disuntikkan oleh DI dapat dibuang dengan aman, karena HttpMessageHandler terkait dikelola oleh pabrik. Instans HttpClient yang disuntikkan dianggap sebagai Transien dari perspektif DI, sedangkan instans HttpMessageHandler dapat dipandang sebagai Cakupan.
HttpMessageHandler instans memiliki cakupan DI mereka sendiri, terpisah dari cakupan aplikasi (misalnya, ASP.NET cakupan permintaan masuk). Untuk informasi selengkapnya, lihat Menggunakan HttpClientFactory di .NET.
Nota
Implementasi IHttpClientFactory (DefaultHttpClientFactory) terkait erat dengan implementasi DI dalam paket Microsoft.Extensions.DependencyInjection NuGet. Jika Anda perlu menggunakan HttpClient tanpa DI atau dengan implementasi DI lainnya, pertimbangkan untuk menggunakan static atau singleton HttpClient yang telah disiapkan dengan PooledConnectionLifetime. Untuk informasi selengkapnya, lihat panduan HttpClient untuk .NET.
Beberapa cara untuk menggunakan IHttpClientFactory
Ada beberapa cara untuk menggunakan IHttpClientFactory di aplikasi Anda:
- Penggunaan dasar
- Gunakan Klien Bernama
- Menggunakan Klien Bertipe
- Menggunakan Klien yang Dihasilkan
Untuk menjaga kejelasan, panduan ini menunjukkan cara paling terstruktur untuk menggunakan IHttpClientFactory, yaitu dengan menggunakan Klien Bertipe (pola Agen Layanan). Namun, semua opsi didokumenkan dan saat ini tercantum dalam artikel ini yang mencakup penggunaan IHttpClientFactory.
Nota
Jika aplikasi Anda memerlukan cookie, mungkin lebih baik untuk menghindari penggunaan IHttpClientFactory di aplikasi Anda. Untuk cara alternatif mengelola klien, lihat Panduan untuk menggunakan klien HTTP.
Cara menggunakan Klien Bertipe dengan IHttpClientFactory
Jadi, apa itu "Typed Client"? Ini hanya HttpClient yang telah dikonfigurasi sebelumnya untuk beberapa tujuan tertentu. Konfigurasi ini dapat mencakup nilai tertentu seperti server dasar, header HTTP, atau waktu habis.
Diagram berikut ini menunjukkan cara penggunaan Klien Tipe dengan IHttpClientFactory:
Gambar 8-4. Menggunakan IHttpClientFactory dengan kelas Klien Bertipe.
Pada gambar di atas, ClientService (digunakan oleh pengontrol atau kode klien) menggunakan HttpClient yang dibuat oleh IHttpClientFactoryterdaftar . Pabrik ini menetapkan HttpMessageHandler dari sebuah kumpulan ke HttpClient.
HttpClient dapat dikonfigurasi dengan kebijakan Polly saat mendaftarkan IHttpClientFactory dalam kontainer DI dengan metode ekstensi AddHttpClient.
Untuk mengonfigurasi struktur di atas, tambahkan IHttpClientFactory di aplikasi Anda dengan menginstal paket Microsoft.Extensions.Http NuGet yang menyertakan metode ekstensi AddHttpClient untuk IServiceCollection. Metode ekstensi ini mendaftarkan kelas DefaultHttpClientFactory internal yang akan digunakan sebagai singleton untuk antarmuka IHttpClientFactory. Ini mendefinisikan konfigurasi sementara untuk HttpMessageHandlerBuilder. Handler pesan ini (HttpMessageHandler objek), diambil dari kumpulan, digunakan oleh HttpClient yang dikembalikan dari pabrik.
Dalam cuplikan berikutnya, Anda dapat melihat bagaimana AddHttpClient() dapat digunakan untuk mendaftarkan Typed Clients (Service Agents) yang perlu menggunakan HttpClient.
// 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>();
Mendaftarkan layanan klien seperti yang ditunjukkan pada cuplikan sebelumnya, menyebabkan DefaultClientFactory menghasilkan HttpClient standar untuk setiap layanan. Klien yang di ketik terdaftar sebagai sementara dengan kontainer DI. Dalam kode sebelumnya, AddHttpClient() mendaftarkan CatalogService, BasketService, OrderingService sebagai layanan sementara sehingga mereka dapat disuntikkan dan dikonsumsi secara langsung tanpa perlu pendaftaran tambahan.
Anda juga dapat menambahkan konfigurasi khusus instans dalam proses pendaftaran untuk, misalnya, mengonfigurasi alamat dasar, dan menambahkan beberapa kebijakan ketahanan, seperti yang ditunjukkan di bawah ini:
builder.Services.AddHttpClient<ICatalogService, CatalogService>(client =>
{
client.BaseAddress = new Uri(builder.Configuration["BaseUrl"]);
})
.AddPolicyHandler(GetRetryPolicy())
.AddPolicyHandler(GetCircuitBreakerPolicy());
Dalam contoh berikutnya ini, Anda dapat melihat konfigurasi salah satu kebijakan di atas:
static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
.WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
}
Anda dapat menemukan lebih banyak detail tentang penggunaan Polly di artikel Berikutnya .
Masa pakai HttpClient
Setiap kali Anda mendapatkan objek HttpClient dari IHttpClientFactory, instance baru dikembalikan. Tetapi setiap HttpClient menggunakan HttpMessageHandler yang dikumpulkan dan digunakan kembali oleh IHttpClientFactory untuk mengurangi konsumsi sumber daya, selama masa pakai HttpMessageHandlerbelum kedaluwarsa.
Pengumpulan handler diinginkan karena setiap handler biasanya mengelola koneksi HTTP yang mendasarnya sendiri; membuat lebih banyak handler daripada yang diperlukan dapat mengakibatkan keterlambatan koneksi. Beberapa handler juga menjaga koneksi tetap terbuka tanpa batas waktu, yang dapat mencegah handler bereaksi terhadap perubahan DNS.
Objek HttpMessageHandler di kumpulan memiliki masa pakai yang merupakan lamanya waktu instans HttpMessageHandler di kumpulan dapat digunakan kembali. Nilai default adalah dua menit, tetapi dapat ditimpa per Klien Bertipe. Untuk menggantinya, panggil SetHandlerLifetime() pada IHttpClientBuilder yang dikembalikan saat membuat klien, sebagaimana ditunjukkan dalam kode berikut:
//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));
Setiap Klien Jenis dapat memiliki nilai masa pakai handler yang dikonfigurasi sendiri. Atur masa pakai ke InfiniteTimeSpan untuk menonaktifkan kedaluwarsa handler.
Implementasikan kelas Klien Bertipe Anda yang menggunakan HttpClient yang telah disuntikkan dan dikonfigurasi
Sebagai langkah sebelumnya, Anda harus mendefinisikan kelas Klien Berjenis, seperti dalam kode sampel: 'BasketService', 'CatalogService', 'OrderingService', dan sebagainya. Klien Berjenis adalah sebuah kelas yang menerima objek HttpClient (disuntikkan melalui konstruktornya) dan menggunakannya untuk memanggil layanan HTTP jarak jauh. Misalnya:
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;
}
}
Klien Jenis (CatalogService dalam contoh) diaktifkan oleh DI (Injeksi Dependensi), yang berarti dapat menerima layanan terdaftar apa pun di konstruktornya, selain HttpClient.
Klien Tipe adalah objek sementara yang efektif, itu berarti instans baru dibuat setiap kali dibutuhkan. Ini menerima instance HttpClient baru setiap kali diinstansiasi. Namun, objek HttpMessageHandler di kumpulan adalah objek yang dipakai ulang oleh beberapa instans HttpClient.
Gunakan kelas Klien Typed Anda
Terakhir, setelah kelas yang diketik diterapkan, Anda dapat mendaftarkannya dan dikonfigurasi dengan AddHttpClient(). Setelah itu Anda dapat menggunakannya dimana saja layanan diinjeksikan oleh DI, seperti di kode halaman Razor atau pengontrol aplikasi web MVC, terlihat pada kode di bawah ini dari eShopOnContainers:
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
}
}
}
Hingga titik ini, cuplikan kode di atas hanya menunjukkan contoh melakukan permintaan HTTP reguler. Tetapi 'sihir' hadir di bagian berikut di mana dijelaskan bagaimana semua permintaan HTTP yang dibuat oleh HttpClient dapat memiliki strategi tangguh seperti mencoba kembali dengan penundaan bertahap, kemampuan pemutus sirkuit, fitur keamanan menggunakan token autentikasi, atau bahkan fitur kustom lainnya. Dan semua ini dapat dilakukan hanya dengan menambahkan kebijakan dan mendelegasikan handler ke Klien Typed terdaftar Anda.
Sumber daya tambahan
panduan HttpClient untuk .NEThttps://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient-guidelines
Menggunakan HttpClientFactory di .NEThttps://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory
Menggunakan HttpClientFactory di ASP.NET Corehttps://learn.microsoft.com/aspnet/core/fundamentals/http-requests
kode sumber HttpClientFactory di repositori GitHub
dotnet/runtimehttps://github.com/dotnet/runtime/tree/release/7.0/src/libraries/Microsoft.Extensions.Http/Polly (pustaka .NET ketahanan dan penanganan kesalahan sementara)https://www.pollydocs.org/
Sebelumnya Berikutnya