При створенні додатку з ASP.NET екземпляр класу HttpClient використовується для створення HTTP-запиту. Використання HttpClient може здаватися простим. Однак деякі потенційні проблеми помічаються лише тоді, коли додаток перебуває під великим навантаженням.
Проблеми, пов'язані з оригінальним класом HttpClient, наданими в .NET:Вхід за гіперпосиланням видно.
HttpClient, реалізуючи IDisposable, оголошення та інстанція його в операторі using не є пріоритетною операцією, оскількиПри випуску об'єкта HttpClient сокет, базовий сокет, цього не відбуваєтьсязаразРеліз, що може спричинити проблеми з виснаженням гнізда.
Проблема насправді не в самому HttpClient, а в конструкторі за замовчуванням HttpClient, оскільки він створює новий фактичний екземпляр HttpMessageHandler з проблемами «виснаження сокета» та змін DNS, згаданими вище.
Створення HttpClient напряму (неправильне використання)
Ініціюємо об'єкт HttpClient безпосередньо та додаємо використання для гарантії виклику методу Dispose, код виглядає так:
Зателефонуйте інтерфейсу 5 разів, надішліть HTTP-запит через HttpClient і перевірте мережеве з'єднання за допомогою наступної команди:
Ви можете побачити, що коли HttpClient запускається, з'єднання між локальним комп'ютером і цільовим сервером єTIME_WAITУ випадку високої паралелізації помилка буде подана наступним чином:
Не вдається підключитися до віддаленого сервера
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Для запитань ви також можете звертатися до:
Створіть HttpClinet за допомогою IHttpClientFactory (правильне використання)
Використовуючи ін'єкцію DI залежностей, IHttpClientFactory — це те саме, що й HttpLinet, який створений за допомогою IHttpClientFactory.
Додайте сервіс до файлу запуску, код виглядає так:
Код контролера HomeController виглядає так:
Ми також використовуємо HttpClinet для надсилання 5 запитів через інтерфейс виклику, і машина встановлює з'єднання лише з цільовим сервером, а з'єднання повторно використовується під час процесу запиту. Як показано нижче:
IHttpClientFactory об'єднує заводські екземпляри HttpMessageHandler у пул для зменшення споживання ресурсів. Коли ви створюєте новий екземпляр HttpClient, ви можете повторно використовувати екземпляр HttpMessageHandler у пулі, якщо термін життя ще не закінчився.
{ "Lifetime": "Singleton", "ServiceType": "System.Net.Http.IHttpClientFactory", "РеалізаціяТип": "Microsoft.Extensions.Http.DefaultHttpClientFactory" }, { "Lifetime": "Singleton", "ServiceType": "System.Net.Http.IHttpMessageHandlerFactory", "РеалізаціяТип": "Microsoft.Extensions.Http.DefaultHttpClientFactory" } IHttpClientFactory реалізовано за замовчуванням як DefaultHttpClientFactory з адресою вихідного коду:Вхід за гіперпосиланням видно.
Використовуючи IHttpClientFactory у додатку з підтримкою DI, ви можете уникнути:
- Вирішіть проблему виснаження ресурсів, поділившись екземпляром HttpMessageHandler.
- Вирішіть застояність DNS, періодично переглядаючи екземпляри HttpMessageHandler.
Крім того, існують інші способи розв'язання вищезазначених проблем за допомогою довготривалих екземплярів SocketsHttpHandler.
- Створіть екземпляр SocketsHttpHandler під час запуску додатку і використовуйте його протягом усього життєвого циклу додатка.
- Налаштуйте PooledConnectionLifetime на відповідне значення на основі часу оновлення DNS.
- Створіть екземпляр HttpClient, використовуючи новий HttpClient (обробник, disposeHandler: false) за потреби.
Вищенаведений підхід вирішує проблеми управління ресурсами подібно до IHttpClientFactory.
- SocketsHttpHandler між екземплярами HttpClientСпільні зв'язки。 Це спільне використання запобігає виснаженню лунки.
- SocketsHttpHandler циклує з'єднання на основі PooledConnectionLifetime, щоб уникнути застарілості DNS.
Для детальнішого використання та налаштування, будь ласка, зверніться сюди:
Вхід за гіперпосиланням видно.
Вхід за гіперпосиланням видно.
|