Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Klasa System.Net.Http.HttpClient wysyła żądania HTTP i odbiera odpowiedzi HTTP z zasobu zidentyfikowanego przez identyfikator URI. Instancja HttpClient to zbiór ustawień, które są stosowane do wszystkich żądań wykonywanych przez tę instancję, a każda instancja używa własnej puli połączeń, co zapewnia izolację jej żądań od innych. Począwszy od platformy .NET Core 2.1, SocketsHttpHandler klasa zapewnia implementację, dzięki czemu zachowanie jest spójne na wszystkich platformach.
Zachowanie DNS
HttpClient Rozpoznaje tylko wpisy DNS po utworzeniu połączenia. Nie śledzi żadnych czasów życia (TTL), które są określone przez serwer DNS. Jeśli wpisy DNS zmieniają się regularnie, co może się zdarzyć w niektórych scenariuszach, klient nie będzie przestrzegać tych aktualizacji. Aby rozwiązać ten problem, można ograniczyć okres istnienia połączenia, ustawiając PooledConnectionLifetime właściwość , aby wyszukiwanie DNS było powtarzane po zastąpieniu połączenia. Rozważmy następujący przykład:
var handler = new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(15) // Recreate every 15 minutes
};
var sharedClient = new HttpClient(handler);
Poprzednia konfiguracja HttpClient
służy do ponownego używania połączeń przez 15 minut. Po upływie przedziału czasu określonego przez PooledConnectionLifetime i zakończeniu ostatniego skojarzonego żądania (jeśli istnieje), to połączenie zostanie zamknięte. Jeśli w kolejce są oczekujące żądania, w razie potrzeby zostanie utworzone nowe połączenie.
Interwał 15-minutowy został wybrany arbitralnie do celów ilustracyjnych. Należy wybrać wartość na podstawie oczekiwanej częstotliwości zmian w systemie DNS lub innych zmianach sieci.
Połączenia w puli
Pula połączeń dla elementu HttpClient jest połączona z bazowym SocketsHttpHandlerelementem .
HttpClient Gdy wystąpienie zostanie usunięte, usuwa wszystkie istniejące połączenia wewnątrz puli. Jeśli później wyślesz żądanie do tego samego serwera, należy ponownie utworzyć nowe połączenie. W związku z tym występuje spadek wydajności z powodu niepotrzebnego tworzenia połączenia. Ponadto porty TCP nie są zwalniane natychmiast po zamknięciu połączenia. (Aby uzyskać więcej informacji na ten temat, zobacz TCP TIME-WAIT
w RFC 9293). Jeśli szybkość żądań jest wysoka, limit systemu operacyjnego dostępnych portów może zostać wyczerpany. Aby uniknąć problemów z wyczerpaniem portów, zalecamy ponowne używanie HttpClient wystąpień dla jak największej liczby żądań HTTP.
Zalecane użycie
Aby podsumować zalecane HttpClient
użycie w zakresie zarządzania okresem istnienia, należy użyć klientów długożyjących i ustawić PooledConnectionLifetime
(.NET Core i .NET 5+) lub klientów krótkotrwałych utworzonych przez IHttpClientFactory
.
W programach .NET Core i .NET 5+:
- Użyj instancji singletona
static
z ustawionym interwałem HttpClient takim jak 2 minuty, w zależności od oczekiwanych zmian DNS. Rozwiązuje to zarówno problemy z wyczerpaniem portów, jak i zmianami DNS bez dodawania IHttpClientFactory. Jeśli musisz mieć możliwość wyśmiewać program obsługi, możesz zarejestrować go oddzielnie.
Napiwek
Jeśli używasz tylko ograniczonej liczby HttpClient wystąpień, jest to również akceptowalna strategia. Ważne jest, aby nie były tworzone i usuwane z każdym żądaniem, ponieważ każdy z nich zawiera pulę połączeń. Użycie więcej niż jednego wystąpienia jest niezbędne w scenariuszach z wieloma serwerami proxy lub do oddzielenia kontenerów plików cookie bez całkowitego wyłączania obsługi plików cookie.
Za pomocą programu IHttpClientFactorymożna mieć wielu, inaczej skonfigurowanych klientów dla różnych przypadków użycia. Należy jednak pamiętać, że klienci utworzoni przez fabrykę mają być krótkotrwałi, a po utworzeniu klienta fabryka nie ma już nad nią kontroli.
Wystąpienia pul HttpMessageHandler fabryki i, jeśli jego okres istnienia nie wygasł, program obsługi można użyć ponownie z puli, gdy fabryka utworzy nowe HttpClient wystąpienie. Ponowne użycie pozwala uniknąć problemów z wyczerpaniem gniazd.
Jeśli zależy ci na konfigurowalności, jaką zapewnia IHttpClientFactory, zalecamy użycie podejścia typizowanego klienta .
- Użyj instancji singletona
W programie .NET Framework użyj polecenia IHttpClientFactory do zarządzania wystąpieniami
HttpClient
. Jeśli nie używasz fabryki i zamiast tego utworzysz nowe wystąpienie klienta dla każdego żądania samodzielnie, możesz wyczerpać dostępne porty.Ostrzeżenie
Jeśli aplikacja wymaga plików cookie, zaleca się unikanie korzystania z usługi IHttpClientFactory. Agregowanie HttpMessageHandler wystąpień powoduje udostępnianie CookieContainer obiektów. Nieprzewidziane CookieContainer udostępnianie może spowodować wyciek plików cookie między niepowiązanymi częściami aplikacji. Ponadto, gdy HandlerLifetime wygaśnie, program obsługi zostanie ponownie wykorzystany, co oznacza, że wszystkie pliki cookie przechowywane w jego CookieContainer zostaną utracone.
Aby uzyskać więcej informacji na temat zarządzania okresem trwałości HttpClient
za pomocą IHttpClientFactory
, zobacz IHttpClientFactory
wytyczne.
Odporność na statycznych klientów
Istnieje możliwość skonfigurowania static
lub singleton klienta do używania dowolnej liczby potoków odporności zgodnie z następującym wzorcem:
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);
}
}
Poprzedni kod:
- Opiera się na pakiecie NuGet Microsoft.Extensions.Http.Resilience .
- Określa przejściowy uchwyt błędów HTTP, skonfigurowany z potokiem ponawiania, który z każdą próbą będzie wykładniczo zwiększał opóźnienie między próbami.
- Ustala czas życia połączenia w puli na piętnaście minut dla elementu
socketHandler
. - Przekazuje
socketHandler
doresilienceHandler
z użyciem logiki ponawiania. - Tworzy wystąpienie udostępnione
HttpClient
dla elementuresilienceHandler
.