При создании приложения с 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 в пул для снижения потребления ресурсов. При создании нового экземпляра HttpMessageHandler вы можете повторно использовать экземпляр HttpMessageHandler в пуле, если срок жизни ещё не истёк.
{ «Lifetime»: «Singleton», "ServiceType": "System.Net.Http.IHttpClientFactory", "ImplementationType": "Microsoft.Extensions.Http.DefaultHttpClientFactory" }, { «Lifetime»: «Singleton», "ServiceType": "System.Net.Http.IHttpMessageHandlerFactory", "ImplementationType": "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.
Для получения дополнительной информации и настройки, пожалуйста, обратитесь к следующему:
Вход по гиперссылке виден.
Вход по гиперссылке виден.
|