|
При создании приложений с помощью ASP.NET HTTP-запросы выполняются с помощью экземпляров класса HttpClient. Использование HttpClient может показаться простым. Однако только когда приложение испытывает большую нагрузку, можно заметить некоторые потенциальные проблемы.
Проблемы, связанные с оригинальным классом HttpClient, поставляемым в .NET: https: //docs.microsoft.com/zh-cn/dotnet/architecture/microservices/implement-resilient-applications/use -httpclientfactory-to-implement-resilient-http-requests
Хотя HttpClient реализует IDisposable, объявление и инстанцирование его в операторе using не является предпочтительным действием, поскольку базовый сокет неосвобождаетсянемедленнопри освобождении объекта HttpClient, что может привести к проблемам с исчерпанием сокета.
Проблема на самом деле заключается не в самом HttpClient, а в конструкторе HttpClient по умолчанию, поскольку он создает новый экземпляр фактического HttpMessageHandler, который имеет проблемы с "исчерпанием сокета" и сменой DNS, упомянутые выше.
Создание HttpClient напрямую (неправильное использование)
Инстанцируйте объект HttpClient напрямую и добавьте using для обеспечения вызова метода Dispose, используя следующий код:
Вызвав интерфейс 5 раз, используйте HttpClient для отправки HTTP-запроса и проверки сетевого соединения следующей командой:
Видно, что при освобождении HttpClient соединение между локальным компьютером и целевым сервером находится в состоянии TIME_WAIT и не освобождается вовремя, а в случае высокого параллелизма будет выдана следующая ошибка:
Невозможно подключиться к удаленному серверу System.Net.Sockets.SocketException: Обычно допускается только одно использование каждого адреса сокета (протокол/сетевой адрес/порт).
Что касается вопроса, см. также:
[Перевод] Неправильное использование HttpClinet может повредить ваше программное обеспечение. h ttps:// www.itsvse.com/thread-10310-1-1.html Создание HttpClinet с помощью IHttpClientFactory (правильное использование)
Используя инъекцию зависимостей DI, IHttpClientFactory и HttpClinet являются одним и тем же, в этой статье для создания HttpClinet используется IHttpClientFactory.
Добавьте службу в файл Startup со следующим кодом:
Код контроллера HomeController выглядит следующим образом:
Вызывая интерфейс, а также используя HttpClinet для отправки 5 запросов, локальная машина только устанавливает соединение с целевым сервером, и это соединение повторно используется во время запроса. На следующей диаграмме показано соединение, повторно используемое в процессе запроса:
IHttpClientFactory объединяет созданные на фабрике экземпляры HttpMessageHandler в пул для снижения потребления ресурсов. Экземпляры HttpMessageHandler в пуле могут быть повторно использованы при создании новых экземпляров HttpClient (если период выживания еще не истек).
{ "Lifetime": "Singleton", "ServiceType": "System.Net.Http.IHttpClientFactory", "ImplementationType": "Microsoft.Extensions.Http.DefaultHttpClientFactory" }, { "Lifetime": "Singleton", "ServiceType": "Microsoft.Extensions.Http. "ServiceType": "System.Net.Http.IHttpMessageHandlerFactory", { "ImplementationType": "Microsoft.Extensions.Http.DefaultHttpClientFactory" } Реализацией IHttpClientFactory по умолчанию является DefaultHttpClientFactory, источник: https: //github.com/dotnet/runtime/blob/main/src/libraries/Microsoft. Extensions.Http/src/DefaultHttpClientFactory.cs
Этого можно избежать, используя IHttpClientFactory в приложениях с поддержкой DI:
- Решение проблемы исчерпания ресурсов путем совместного использования экземпляров HttpMessageHandler.
- Решение проблемы устаревания DNS путем периодического циклического использования экземпляров HttpMessageHandler.
Существуют и другие способы использования долгоживущих экземпляров SocketsHttpHandler для решения этих проблем.
- создает экземпляр SocketsHttpHandler при запуске приложения и использует его на протяжении всего жизненного цикла приложения.
- Настройте PooledConnectionLifetime на соответствующее значение, основанное на времени обновления DNS.
- При необходимости создайте экземпляр HttpClient с помощью new HttpClient(handler, disposeHandler: false).
Приведенный выше подход решает проблему управления ресурсами аналогично тому, как ее решает IHttpClientFactory.
- SocketsHttpHandler разделяет соединения между экземплярами HttpClient.
- Такой обмен предотвращает исчерпание сокетов. SocketsHttpHandler зацикливает соединения на основе PooledConnectionLifetime, чтобы избежать проблем с устареванием DNS.
Подробнее об использовании и настройке см:
h ttps:// docs.microsoft.com/zh-cn/aspnet/core/fundamentals/http-requests?view=aspnetcore-6.0 h ttps:// docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-6.0
|
Предыдущий: [Перевод] Неправильное использование HttpClient разрушит ваше программное обеспечение!Следующая: [Практическая] Плагин интернационализации jQuery Datatables
|