Bagikan melalui


Panduan untuk menggunakan HttpClient

Kelas System.Net.Http.HttpClient mengirim permintaan HTTP dan menerima respons HTTP dari sumber daya yang diidentifikasi oleh URI. Instans HttpClient adalah kumpulan pengaturan yang diterapkan ke semua permintaan yang dijalankan oleh instans tersebut, dan setiap instans menggunakan kumpulan koneksinya sendiri, yang mengisolasi permintaannya dari yang lain. Mulai dari .NET Core 2.1, SocketsHttpHandler kelas menyediakan implementasi, membuat perilaku konsisten di semua platform.

Perilaku DNS

HttpClient hanya menyelesaikan entri DNS saat koneksi dibuat. Ini tidak melacak waktu hidup (TTL) yang ditentukan oleh server DNS. Jika entri DNS berubah secara teratur, yang dapat terjadi dalam beberapa skenario, klien tidak akan menghormati pembaruan tersebut. Untuk mengatasi masalah ini, Anda dapat membatasi masa pakai koneksi dengan mengatur PooledConnectionLifetime properti, sehingga pencarian DNS diulang saat koneksi diganti. Pertimbangkan contoh berikut:

var handler = new SocketsHttpHandler
{
    PooledConnectionLifetime = TimeSpan.FromMinutes(15) // Recreate every 15 minutes
};
var sharedClient = new HttpClient(handler);

HttpClient dikonfigurasi untuk menggunakan kembali koneksi selama 15 menit. Setelah rentang waktu yang ditentukan oleh PooledConnectionLifetime telah berlalu dan koneksi telah menyelesaikan permintaan terkait terakhirnya (jika ada), koneksi ini ditutup. Jika ada permintaan yang menunggu dalam antrean, koneksi baru akan dibuat jika diperlukan.

Interval 15 menit dipilih secara segan-segan untuk tujuan ilustrasi. Anda harus memilih nilai berdasarkan frekuensi DNS yang diharapkan atau perubahan jaringan lainnya.

Koneksi berbasis pool

Kumpulan koneksi untuk HttpClient ditautkan ke SocketsHttpHandler bawahnya. Ketika instance HttpClient dibuang, instance tersebut menghapus semua koneksi yang ada di dalam kolam. Jika nanti Anda mengirim permintaan ke server yang sama, koneksi baru harus dibuat ulang. Akibatnya, ada hukuman performa untuk pembuatan koneksi yang tidak perlu. Selain itu, port TCP tidak dirilis segera setelah penutupan koneksi. (Untuk informasi selengkapnya tentang itu, lihat TCP TIME-WAIT di RFC 9293.) Jika tingkat permintaan tinggi, batas sistem operasi port yang tersedia mungkin habis. Untuk menghindari masalah kekurangan port, kami merekomendasikan untuk menggunakan kembali HttpClient instans sebanyak mungkin dalam permintaan HTTP.

Untuk meringkas penggunaan HttpClient yang direkomendasikan dalam hal manajemen siklus hidup, Anda harus menggunakan klien berumur panjang dan mengatur (.NET Core dan .NET 5+) atau klien dengan umur pendek yang dibuat oleh PooledConnectionLifetime.

  • Di .NET Core dan .NET 5+:

    • Gunakan instans staticsingleton, dengan HttpClient diatur ke interval yang diinginkan, seperti 2 menit, bergantung pada perubahan DNS yang diharapkan. Ini memecahkan masalah kelelahan port dan perubahan DNS tanpa menambahkan overhead IHttpClientFactory. Jika Anda harus dapat mengejek handler Anda, Anda dapat mendaftarkannya secara terpisah.

    Petunjuk

    Jika Anda hanya menggunakan sejumlah instance HttpClient terbatas, itu merupakan strategi yang dapat diterima juga. Yang penting adalah bahwa mereka tidak dibuat dan dibuang dengan setiap permintaan, karena masing-masing berisi kumpulan koneksi. Menggunakan lebih dari satu instans diperlukan untuk skenario dengan beberapa proksi atau untuk memisahkan kontainer cookie tanpa sepenuhnya menonaktifkan penanganan cookie.

    • Menggunakan IHttpClientFactory, Anda dapat memiliki beberapa klien yang dikonfigurasi secara berbeda untuk kasus penggunaan yang berbeda. Namun, ketahuilah bahwa klien yang dibuat pabrik dimaksudkan untuk berumur pendek, dan setelah klien dibuat, pabrik tidak lagi memiliki kontrol atasnya.

      Pabrik mengumpulkan instans HttpMessageHandler, dan jika masa berlakunya belum habis, handler dapat digunakan kembali dari kumpulan ketika pabrik membuat instans HttpClient baru. Penggunaan kembali ini menghindari masalah kelelahan soket.

      Jika Anda menginginkan konfigurasi yang disediakan oleh IHttpClientFactory, sebaiknya gunakan pendekatan typed-client.

  • Di .NET Framework, gunakan IHttpClientFactory untuk mengelola instans Anda HttpClient . Jika Anda tidak menggunakan fabrik dan malah membuat instans klien baru untuk setiap permintaan secara manual, Anda dapat menghabiskan koneksi yang tersedia.

    Peringatan

    Jika aplikasi Anda memerlukan cookie, disarankan untuk menghindari penggunaan IHttpClientFactory. Menggabungkan instans HttpMessageHandler menghasilkan berbagi objek CookieContainer. Berbagi yang tidak terduga CookieContainer mungkin membocorkan cookie antara bagian aplikasi yang tidak terkait. Selain itu, ketika HandlerLifetime kedaluwarsa, handler didaur ulang, yang berarti bahwa semua cookie yang disimpan di dalamnya CookieContainer hilang.

Untuk informasi selengkapnya tentang mengelola HttpClient masa pakai dengan IHttpClientFactory, lihat IHttpClientFactory panduan.

Ketahanan dengan klien statis

Dimungkinkan untuk mengonfigurasi static klien atau singleton untuk menggunakan sejumlah alur ketahanan menggunakan pola berikut:

using Microsoft.Extensions.Http.Resilience;
using Polly;

class MyClass
{
    static HttpClient? s_httpClient;

    MyClass()
    {
        var retryPipeline = new ResiliencePipelineBuilder<HttpResponseMessage>()
            .AddRetry(new HttpRetryStrategyOptions
            {
                BackoffType = DelayBackoffType.Exponential,
                MaxRetryAttempts = 3
            })
            .Build();

        var socketHandler = new SocketsHttpHandler
        {
            PooledConnectionLifetime = TimeSpan.FromMinutes(15)
        };
        var resilienceHandler = new ResilienceHandler(retryPipeline)
        {
            InnerHandler = socketHandler,
        };

        s_httpClient = new HttpClient(resilienceHandler);
    }
}

Kode sebelumnya:

  • Bergantung pada paket NuGet Microsoft.Extensions.Http.Resilience .
  • Menentukan handler kesalahan HTTP yang bersifat sementara, yang dikonfigurasi dengan alur retry yang dengan setiap upaya akan meningkatkan interval penundaan secara eksponensial.
  • Menentukan masa pakai koneksi terkumpul lima belas menit untuk socketHandler.
  • Mengoper socketHandler ke resilienceHandler dengan logika coba lagi.
  • Membuat sebuah instans HttpClient yang dibagikan yang ditentukan oleh resilienceHandler.

Lihat juga