Saya telah menggunakan HttpClient secara salah selama bertahun-tahun, tetapi akhirnya mimpi buruk itu datang. Situs web saya tidak stabil dan pelanggan saya sangat marah dan dengan perbaikan sederhana, kinerjanya sangat meningkat dan ketidakstabilan dihilangkan.
Pada saat yang sama, saya benar-benar meningkatkan kinerja aplikasi saya dengan penggunaan soket yang lebih efisien.
Layanan mikro bisa menjadi masalah yang sulit untuk ditangani. Karena lebih banyak layanan ditambahkan dan aplikasi monolitik terurai, cenderung ada lebih banyak jalur komunikasi antar layanan. Ada banyak opsi komunikasi, tetapi HTTP adalah opsi yang sangat populer. Jika layanan mikro dibangun dalam C# atau bahasa .NET apa pun, kemungkinan Anda sudah menggunakan HttpClient.
Masalahnya terletak
Pernyataan using adalah fitur C# yang menangani objek satu kali. Setelah blok penggunaan selesai, maka objek satu kali (dalam hal ini HttpClient) berada di luar cakupan dan dibuang. Panggil metode pembuangan dan bersihkan sumber daya apa pun yang digunakan. Ini adalah pola yang sangat khas di .NET yang kita gunakan untuk segala hal mulai dari database hingga penulis alur. Faktanya, objek apa pun dengan sumber daya eksternal yang harus dibersihkan menggunakan antarmuka IDisposable tersebut.
Dan Anda tidak bisa disalahkan karena ingin membungkusnya dengan menggunakan. Pertama, dianggap sebagai praktik yang baik untuk melakukannya. Faktanya, dokumentasi resmi Microsoft menggunakan:
Secara umum, saat menggunakan objek IDisposable, objek tersebut harus dideklarasikan dan dibuat instance dalam pernyataan useing. Kedua, semua kode yang mungkin pernah Anda lihat...... Awal HttpClient akan memberi tahu Anda untuk menggunakan blok pernyataan using, termasuk dokumentasi terbaru ASP.NET situs itu sendiri. Hal yang sama dikatakan dalam artikel di Internet.
Tapi HttpClient berbeda. Meskipun mengimplementasikan antarmuka IDisposable, sebenarnya ini adalah objek bersama. Ini berarti bahwa di balik layar itu masuk kembali dan aman untuk benang. Anda harus membagikan instans HttpClient selama masa pakai aplikasi Anda, daripada membuat instans baru untuk setiap eksekusi. HttpClient mari kita lihat alasannya.
Lihat sendiri
Berikut adalah program sederhana untuk mendemonstrasikan HttpClient:
Ini akan diarahkan ke http://aspnetmonsters.comBuka 10 permintaan dan lakukan GET, kami hanya mencetak kode status, sehingga kami tahu itu berfungsi. Outputnya adalah:
Tunggu, masih ada lagi!
Semua pekerjaan dan semuanya benar untuk dunia. kecuali tidak. Jika kita mengeluarkan alat netstat dan melihat status soket pada mesin yang menjalankannya, kita akan melihat:
C:\code\socket>NETSTAT.EXE ... Alamat Lokal Proto Alamat Asing Negara 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 DIDIRIKAN ... Yah, itu aneh...... Aplikasi telah keluar, tetapi masih ada banyak koneksi ini yang terbuka ke komputer Azure yang menghosting situs web ASP.NET Monsters. Mereka berada diTIME_WAITstatus, yang berarti bahwa koneksi telah ditutup di satu sisi (milik kami), tetapi kami masih menunggu untuk melihat apakah ada paket lain yang masuk karena mungkin telah tertunda di jaringan di suatu tempat. Berikut diagram status TCP/IP:
Windows akan tetap terhubung dalam status ini selama 240 detik (seperti yang diatur dengan pengaturan [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]). Windows memiliki batasan seberapa cepat Anda dapat membuka soket baru, jadi jika Anda kehabisan kumpulan koneksi, maka Anda mungkin melihat kesalahan seperti ini:
Tidak dapat terhubung ke server jarak jauh
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted. Mencarinya di Google akan memberi Anda beberapa saran buruk tentang mengurangi batas waktu koneksi. Faktanya, saat berjalan di server dengan HttpClient atau aplikasi yang dibangun serupa dengan benar, mengurangi batas waktu dapat menyebabkan konsekuensi buruk lainnya. Kita perlu memahami apa arti "benar" dan memecahkan masalah yang mendasarinya, bukan mengutak-atik variabel tingkat mesin.
Perbaiki
Jika kita membagikan instance HttpClient maka kita dapat mengurangi limbah soket dengan menggunakannya kembali:
Perhatikan bahwa untuk seluruh aplikasi, kita hanya memiliki satu instance bersama. HttpClient masih berfungsi seperti sebelumnya (sebenarnya sedikit lebih cepat karena penggunaan kembali soket). Netstat sekarang hanya menampilkan:
TCP 10.211.55.6:12254 waws-prod-bay-017:http DIDIRIKAN Dalam skenario produksi, jumlah soket saya rata-rata sekitar 4000 dan memuncak di lebih dari 5000, secara efektif menekan sumber daya yang tersedia di server, menyebabkan layanan mogok. Setelah menerapkan perubahan, jumlah soket yang digunakan turun dari rata-rata lebih dari 4000 menjadi kurang dari 400 secara konsisten, biasanya sekitar 100.
Ini adalah bagian dari bagan dari alat pemantauan kami yang menunjukkan apa yang terjadi setelah kami menyebarkan sejumlah bukti perbaikan ke sejumlah layanan mikro tertentu.
Itu dramatis. Jika Anda memiliki jenis beban apa pun, Anda perlu mengingat dua hal ini:
Buat HttpClient Anda statis. Jangan membuang atau mengemas penggunaan Anda kecuali Anda secara eksplisit mencari perilaku tertentu (seperti menyebabkan layanan Anda gagal). Klien Http
ringkasan
Masalah kelelahan soket yang telah kami perjuangkan selama berbulan-bulan telah hilang, dan pelanggan kami mengadakan parade virtual. Saya tidak bisa meremehkan betapa tidak jelasnya kesalahan ini. Selama bertahun-tahun, kami telah terbiasa berurusan dengan objek yang diimplementasikan, IDisposable, dan banyak alat pemfaktoran ulang seperti R# dan CodeRush benar-benar memperingatkan Anda jika Anda tidak melakukannya. Dalam hal ini, membuang HttpClient adalah pendekatan yang salah. HttpClient mengimplementasikan IDisposable dan mendorong perilaku buruk sangat disayangkan
Asli:Login hyperlink terlihat.
|