Aracılığıyla paylaş


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 HttpClient kullanımı yaşam süresi yönetimi açısından özetlemek için, uzun ömürlü istemciler kullanmanız ve tarafından IHttpClientFactoryoluş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.

  • .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 socketHandleron beş dakikalık havuza alınan bağlantı ömrünü tanımlar.
  • socketHandler resilienceHandler öğesini yeniden deneme mantığıyla iletir.
  • Verilen bir HttpClient örneği resilienceHandleroluşturur.

Önemli

Kitaplık Microsoft.Extensions.Http.Resilience şu anda deneysel olarak işaretlenmiştir ve gelecekte değişebilir.

Ayrıca bkz.