HttpClient kullanma yönergeleri
sınıfı System.Net.Http.HttpClient HTTP istekleri gönderir ve URI tarafından tanımlanan bir kaynaktan HTTP yanıtları alır. Örnek HttpClient , bu örnek tarafından yürütülen tüm isteklere uygulanan bir ayar koleksiyonudur ve her örnek, isteklerini diğerlerinden yalıtan kendi bağlantı havuzunu kullanır. .NET Core 2.1'den başlayarak sınıfı SocketsHttpHandler , tüm platformlarda davranışı tutarlı hale getirerek uygulamayı sağlar.
DNS davranışı
HttpClient yalnızca bir bağlantı oluşturulduğunda DNS girdilerini çözümler. DNS sunucusu tarafından belirtilen yaşam süresi (TTL) sürelerini izlemez. DNS girişleri düzenli olarak değişirse ve bu bazı senaryolarda gerçekleşebilirse istemci bu güncelleştirmelere saygı duymaz. Bu sorunu çözmek için, özelliği ayarlayarak PooledConnectionLifetime bağlantının ömrünü sınırlayabilirsiniz; böylece bağlantı değiştirildiğinde DNS araması yinelenir. Aşağıdaki örneği inceleyin:
var handler = new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(15) // Recreate every 15 minutes
};
var sharedClient = new HttpClient(handler);
Önceki HttpClient
, bağlantıları 15 dakika boyunca yeniden kullanacak şekilde yapılandırılmıştır. tarafından PooledConnectionLifetime belirtilen zaman aralığı dolduktan ve bağlantı son ilişkili isteğini (varsa) tamamladıktan sonra bu bağlantı kapatılır. Kuyrukta bekleyen istekler varsa, gerektiğinde yeni bir bağlantı oluşturulur.
15 dakikalık aralık, çizim amacıyla rastgele seçilmiştir. Değeri, beklenen DNS sıklığına veya diğer ağ değişikliklerine göre seçmelisiniz.
Havuza alınan bağlantılar
için HttpClient bağlantı havuzu, temel alınan SocketsHttpHandleröğesine bağlıdır. Örnek atıldığında, havuzun HttpClient içindeki tüm mevcut bağlantıları atar. Daha sonra aynı sunucuya istek gönderirseniz yeni bir bağlantı yeniden oluşturulmalıdır. Sonuç olarak, gereksiz bağlantı oluşturma için bir performans cezası vardır. Ayrıca, TCP bağlantı noktaları bağlantı kapatma işleminden hemen sonra serbest bırakılmaz. (Bu konuda daha fazla bilgi için bkz. RFC 9293'te TCPTIME-WAIT
.) İsteklerin oranı yüksekse, kullanılabilir bağlantı noktalarının işletim sistemi sınırı tükenmiş olabilir. Bağlantı noktası tükenme sorunlarını önlemek için mümkün olduğunca çok HTTP isteği için örnekleri yeniden kullanmanızı HttpClient öneririz.
Önerilen kullanım
Önerilen HttpClient
kullanımı yaşam süresi yönetimi açısından özetlemek için, uzun ömürlü istemciler kullanmanız ve tarafından IHttpClientFactory
oluşturulan (.NET Core ve .NET 5+) veya kısa süreli istemcileri ayarlamanız PooledConnectionLifetime
gerekir.
.NET Core ve .NET 5+ içinde:
- Beklenen DNS değişikliklerine bağlı olarak, istenen zaman aralığına (örneğin 2 dakika) ayarlanmış bir
static
veya tekil HttpClient örnek PooledConnectionLifetime kullanın. Bu, yükünü IHttpClientFactoryeklemeden hem bağlantı noktası tükenmesi hem de DNS değişiklikleri sorunlarını çözer. İşleyicinizle dalga geçebilmeniz gerekiyorsa ayrı olarak kaydedebilirsiniz.
İpucu
Yalnızca sınırlı sayıda HttpClient örnek kullanıyorsanız, bu da kabul edilebilir bir stratejidir. Önemli olan, her biri bir bağlantı havuzu içerdiği için bunların her istekle oluşturulmaması ve atılmamasıdır. Birden çok proxy içeren senaryolarda veya tanımlama bilgisi işlemeyi tamamen devre dışı bırakmadan tanımlama bilgisi kapsayıcılarını ayırmak için birden fazla örnek kullanmak gerekir.
kullanarak IHttpClientFactory, farklı kullanım örnekleri için birden çok farklı yapılandırılmış istemciniz olabilir. Ancak, fabrika tarafından oluşturulan istemcilerin kısa ömürlü olması amaçlandığını ve istemci oluşturulduktan sonra fabrikanın artık bu istemci üzerinde denetimi olmadığını unutmayın.
Fabrika örnekleri havuza HttpMessageHandler alır ve ömrü dolmadıysa, fabrika yeni HttpClient bir örnek oluşturduğunda havuzdan bir işleyici yeniden kullanılabilir. Bu yeniden kullanım, yuva tükenme sorunlarını önler.
Sağlayan yapılandırılabilirliği IHttpClientFactory istiyorsanız, typed-client yaklaşımını kullanmanızı öneririz.
- Beklenen DNS değişikliklerine bağlı olarak, istenen zaman aralığına (örneğin 2 dakika) ayarlanmış bir
.NET Framework'te, örneklerinizi
HttpClient
yönetmek için kullanınIHttpClientFactory. Fabrikayı kullanmaz ve bunun yerine her istek için kendiniz yeni bir istemci örneği oluşturursanız, kullanılabilir bağlantı noktalarını tüketebilirsiniz.İpucu
Uygulamanız tanımlama bilgileri gerektiriyorsa, otomatik tanımlama bilgisi işlemeyi devre dışı bırakmayı veya uygulamasından kaçınmayı IHttpClientFactorygöz önünde bulundurun. Örneklerin havuzalanması HttpMessageHandler nesne paylaşımına CookieContainer neden olur. Tahmin edilmeyen CookieContainer nesne paylaşımı genellikle yanlış koda neden olur.
ile kullanım ömrünü yönetme HttpClient
hakkında daha fazla bilgi için yönergelere bakınIHttpClientFactory
.IHttpClientFactory
Statik istemcilerle dayanıklılık
Aşağıdaki deseni kullanarak bir veya tekil istemciyi herhangi bir static
sayıda dayanıklılık işlem hattını kullanacak şekilde yapılandırmak mümkündür:
using System;
using System.Net.Http;
using Microsoft.Extensions.Http;
using Microsoft.Extensions.Http.Resilience;
using Polly;
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,
};
var httpClient = new HttpClient(resilienceHandler);
Yukarıdaki kod:
- Microsoft.Extensions.Http.Resilience NuGet paketine dayanır.
- Yeniden deneme işlem hattıyla yapılandırılan ve her denemede üstel geri alma gecikme aralıkları olacak geçici bir HTTP hata işleyicisi belirtir.
- için
socketHandler
on beş dakikalık havuza alınan bağlantı ömrünü tanımlar. socketHandler
resilienceHandler
öğesini yeniden deneme mantığıyla iletir.- Verilen bir
HttpClient
örneğiresilienceHandler
oluşturur.
Önemli
Kitaplık Microsoft.Extensions.Http.Resilience
şu anda deneysel olarak işaretlenmiştir ve gelecekte değişebilir.