Bu makale makine çevirisi ayna makalesidir, orijinal makaleye geçmek için lütfen buraya tıklayın.

Görünüm: 6079|Yanıt: 4

[Kaynak] HttpClient'ı yanlış kullanmak yazılımınızı bozabilir

[Bağlantıyı kopyala]
Yayınlandı 14.05.2022 17:11:56 | | | |
Yıllardır HttpClient'ı yanlış kullanıyorum ama sonunda kabus geldi. Web sitem istikrarsızdı ve müşterilerim çok öfkeliydi, basit bir çözümle performans büyük ölçüde arttı ve istikrarsızlık ortadan kaldırıldı.



Aynı zamanda, uygulamamın performansını daha verimli soket kullanımıyla gerçekten geliştirdim.

Mikroservislerle başa çıkmak zor bir sorun olabilir. Daha fazla hizmet eklendikçe ve monolitik uygulamalar parçalandıkça, hizmetler arasında iletişim yolları giderek artmaya eğilimlidir. Birçok iletişim seçeneği vardır, ancak HTTP çok popüler bir seçenektir. Mikroservis C# veya herhangi bir .NET dilinde yerleşik ise, muhtemelen zaten HttpClient kullanıyorsunuzdur.


Sorun şu

Using ifadesi, tek seferlik nesneleri yöneten bir C# özelliğidir. Kullanım bloğu tamamlandığında, tek seferlik nesne (bu durumda HttpClient) kapsam dışı olur ve elden çıkar. İmha yöntemini çağırın ve kullanılan kaynakları temizleyin. Bu, .NET'te veritabanından akış yazarına kadar her şey için kullandığımız çok tipik bir desendir. Aslında, temizlenmesi gereken harici bir kaynağı olan herhangi bir nesne, o IDisposable arayüzü kullanır.

Ve bunu kullanmak istediğin için suçlanamazsın. İlk olarak, bunu yapmak iyi bir uygulama olarak kabul edilir. Aslında, Microsoft'un resmi dokümantasyonu şunları kullanıyor:


Genel olarak, IDisposable bir nesne kullanılırken, using ifadesinde bildirilmeli ve örneklenmelidir.
İkincisi, gördüğünüz tüm kodlar...... HttpClient'ın başı, site ASP.NET en güncel dokümantasyonu dahil olmak üzere using statement bloğunu kullanmanızı söyler. Aynı şey internetteki makalede de söylenir.

Ama HttpClient farklı. IDisposable arayüzü uygulasa da, aslında paylaşılan bir nesnedir. Bu, perde arkasında yeniden giriş ve konu için güvenli olduğu anlamına gelir. Her çalıştırma için yeni bir örnek oluşturmak yerine, uygulamanızın ömrü boyunca bir HttpClient örneğini paylaşmalısınız. HttpClient, nedenini görelim.

Kendin görün

İşte HttpClient'ı göstermek için basit bir program:

Bu adres şu adrese yönlendirilecektir  http://aspnetmonsters.com10 istek açıp GET yapıyoruz, sadece durum kodunu yazdırıyoruz, böylece çalıştığını biliyoruz. Çıktı şu olacak:

Bekle, daha fazlası var!

Her şey ve her şey dünya için doğru olur. ama öyle değil. Netstat aracını çıkarıp onu çalıştıran makinedeki soket durumuna bakarsak, şunları görürüz:

C:\code\socket>NETSTAT.EXE
...
  Proto Yerel Adres Yabancı Adres Durumu
  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 KURULDU
...
Garip...... Uygulama kapatıldı, ancak ASP.NET Monsters web sitesini barındıran Azure makinesine hala açık birçok bağlantı var. GirdilerTIME_WAITdurum, yani bağlantının bir tarafında (bizimki) kapatıldığını gösteriyor, ancak ağda bir yerde gecikmeli olabileceği için başka paketlerin gelip gelmediğini görmek için hâlâ bekliyoruz. İşte TCP/IP durumunun bir diyagramı:



Windows bu durumda 240 saniye boyunca bağlı kalır ([HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay] ayarıyla ayarlandığı gibi). Windows'un yeni bir soketi ne kadar hızlı açabileceğinize dair bir sınırı var, bu yüzden bağlantı havuzlarınız biterse böyle bir hata görebilirsiniz:

Uzak sunucuya bağlanamıyor
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Google'da arama yaparsanız, bağlantı zaman duruşunu azaltmak için kötü tavsiyeler verir. Aslında, HttpClient veya benzer şekilde oluşturulmuş bir uygulama ile bir sunucuda doğru çalışırken, zaman aşımlarının azaltılması başka olumsuz sonuçlara yol açabilir. "Doğru"nun ne anlama geldiğini anlamalı ve temel sorunu çözmemiz gerekiyor, makine düzeyindeki değişkenlerle uğraşmamalıyız.

Düzelt

Bir HttpClient örneğini paylaşırsak, soket israfını tekrar kullanarak azaltabiliriz:

Tüm uygulama için sadece bir ortak örnek olduğunu unutmayın. HttpClient hâlâ eskisi gibi çalışıyor (aslında soket yeniden kullanımı nedeniyle biraz daha hızlı). Netstat artık sadece şunları gösteriyor:

TCP 10.211.55.6:12254 waws-prod-bay-017:http KURULDU
Üretim senaryosunda soket sayım ortalama 4000 civarında ve 5000'in üzerinde en yüksek seviyeye ulaşıyor, bu da sunucudaki mevcut kaynakları sıkıştırıyor ve servisin çökmesine neden oluyor. Değişiklik uygulandıktan sonra, kullanılan soket sayısı ortalama 4000'den sürekli olarak 400'ün altına düştü, genellikle 100 civarına düştü.

Bu, izleme aracımızdan alınan ve belirli sayıda düzeltme kanıtı belirli sayıda mikroservise dağıttıktan sonra ne olduğunu gösteren bir grafikin parçasıdır.




Dramatikti. Herhangi bir yük türü varsa, şu iki şeyi aklınızda tutmalısınız:

HttpClient cihazınızı statik yapın.
Belirli bir davranış (örneğin hizmetinizin başarısız olmasına sebep olmak gibi) aradığınız sürece kullanımınızı çöpe atmayın veya paketlemeyin. HttpClient


özet

Aylarca mücadele ettiğimiz soket tükenmesi sorunu ortadan kalktı ve müşterilerimiz sanal bir geçit töreni yapıyor. Bu hatanın ne kadar belirgin olmadığını küçümseyemem. Yıllar içinde uygulanan nesnelerle, IDisposable'le uğraşmaya alıştık ve R# ile CodeRush gibi birçok refaktör aracı aslında bunu yapmazsanız sizi uyarıyor. Bu durumda, HttpClient'ı ortadan kaldırmak yanlış bir yaklaşımdır. HttpClient IDisposable uygular ve kötü davranışları teşvik eder bu talihsiz

Özgün:Bağlantı girişi görünür.




Önceki:ASP.NET Core, IIS'de Süreç İçi ve Süreç Dışı modelleri barındırır
Önümüzdeki:ASP.NET Core (XV), HTTP istekleri göndermek için HttpClient kullanır
 Ev sahibi| Yayınlandı 14.05.2022 17:25:22 |
TCP TIME_WAIT, normal bir TCP protokol işlemidir; yani son FIN-ACK geçtikten sonra, istemci çift maksimum ömür süresinin (MSL) geçmesini bekleyecek ve uzaktan TCP'nin bağlantı sonlandırma talebinin onayını almasını sağlar. Varsayılan olarak, MSL 2 dakikadır. İki MSL olarak bilinen TIME_WAIT 4 dakikaya kadar kalabilirsiniz.

https://docs.microsoft.com/en-us ... t-from-netstat.html
Yayınlandı 14.05.2022 22:35:22 |
Öğrenmeyi öğren
Yayınlandı 19.05.2022 09:39:05 |
Hepsi Çince, ama cümlelerle bağlantılı olduğunda anlayamıyorum
 Ev sahibi| Yayınlandı 6.11.2023 07:16:05 |
test
Feragatname:
Code Farmer Network tarafından yayımlanan tüm yazılım, programlama materyalleri veya makaleler yalnızca öğrenme ve araştırma amaçları içindir; Yukarıdaki içerik ticari veya yasa dışı amaçlarla kullanılamaz, aksi takdirde kullanıcılar tüm sonuçları ödemelidir. Bu sitedeki bilgiler internetten alınmakta olup, telif hakkı anlaşmazlıklarının bu siteyle hiçbir ilgisi yoktur. Yukarıdaki içeriği indirmeden sonraki 24 saat içinde bilgisayarınızdan tamamen silmelisiniz. Programı beğendiyseniz, lütfen orijinal yazılımı destekleyin, kayıt satın alın ve daha iyi orijinal hizmetler alın. Herhangi bir ihlal olursa, lütfen bizimle e-posta yoluyla iletişime geçin.

Mail To:help@itsvse.com