Вопрос или проблема
В переходе от .NET Framework к .NET (ранее .NET Core) Microsoft представила новый HTTP-клиент под названием System.Net.Http.HttpClient, и System.Net.HttpWebRequest теперь помечен как устаревший.
Разбираясь с приложением, которое использует смесь этих технологий, я обнаружил, что HttpClient не учитывает TTL от DNS. В настоящее время существует официальное решение для установки максимального времени жизни для всех соединений. Это кажется мне безумным, потому что:
- время жизни определяет разработчик, а не DNS. Если поставщик услуг хочет изменить свой TTL, он этого не поймает.
- соединение закрывается и воссоздается, даже если DNS не изменился. Просто потому, что TTL составляет 5 минут, это не означает, что каждый 5 минут будет новый IP.
До этого решения вообще не было решения в .NET Core, насколько я знаю, но вы могли настраивать объекты ServicePoint в .NET Framework.
Кажется, что Microsoft запустила новый HTTP-клиент, встроила его в свои новые SDK, активно его продвигала, сделала старый устаревшим и случайно забыла про DNS.
В моем сценарии у нас есть непрерывные фоновый задачи (Azure WebJobs), которые обращаются к нескольким HTTP API, работающим на виртуальной машине (Azure App Service), так что у нас есть возможность повторно использовать соединения больше, чем если бы мы использовали бессерверные вычисления.
Похоже на общую ошибку. Я что-то неправильно понял? Я раздуваю проблему из мухи?
Ссылка: https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient-guidelines
Ответ или решение
Проблема повторного использования HTTP-соединений в .NET HttpClient
Переход от .NET Framework к .NET (ранее .NET Core) принес значительные изменения в реализации HTTP-клиента. Новая библиотека System.Net.Http.HttpClient
была представлена как замена устаревшему HttpWebRequest
. Однако, в процессе этой эволюции возникли некоторые проблемы, которые стоит обсудить, особенно в контексте использования соединений и обработки DNS с TTL.
1. Проблемы с TTL и жизненным циклом соединений
Суть проблемы заключается в том, что HttpClient
не учитывает время жизни DNS-записей (TTL). Вместо этого Microsoft предложила установить максимальный срок жизни для соединений в коде приложения. Это вызывает два основных вопроса:
-
Произвольное значение TTL: Поскольку разработчик сам устанавливает время жизни соединений, вероятность несоответствия с реальным TTL, установленным на уровне DNS, возрастает. Это значит, что если провайдер изменит TTL своей записи, ваше приложение не сможет отреагировать на это изменение автоматически.
-
Закрытие и восстановление соединений: Закрытие соединения и его повторное создание даже тогда, когда DNS не изменился, приводит к неэффективному использованию ресурсов. TTL в 5 минут не означает, что IP-адрес изменится каждые 5 минут. Принуждение к перезапуску соединения может лишить приложение возможности оптимально использовать установленные соединения.
2. Исторический контекст
Ранее, в .NET Framework, разработчики имели возможность настраивать объекты ServicePoint
, которые позволяли более гибко управлять соединениями и учитывать состояние DNS. После перехода на HttpClient
, эта возможность была значительно ограничена, и, как выясняется, Microsoft недостаточно учла необходимость этих параметров для оптимизации работы сети.
3. Последствия для приложений
В вашем сценарии, где используются непрерывные фоновый процессы (например, Azure WebJobs), возможность повторного использования HTTP-соединений может значительно повысить эффективность и производительность. Если соединения постоянно закрываются и восстанавливаются, это может привести к увеличению времени ответа и дополнительным накладным расходам на ресурсы.
4. Проблемы с масштабированием и экономией ресурсов
Масштабируемые веб-службы требуют надежной работы с HTTP-соединениями. Резкое закрытие и повторное открытие соединений приведет к ухудшению общей производительности, особенно когда на сервер направляется большое количество запросов. Это также может вызвать проблемы с задержкой и увеличенной нагрузкой на сервер.
5. Заключение
Следует рассматривать эти ограничения как значительный вызов для разработчиков, использующих HttpClient
в .NET. Хотя идея установки максимального срока жизни соединений может показаться разумной на первый взгляд, она требует глубокой переработки подходов к работе с сетью. Возможно, неправильное восприятие этой функциональности связано с недостаточной документацией по данному вопросу и недостаточной гибкостью реализации.
В итоге, это не значит, что HttpClient
изначально "сломанный", но эта реализация требует внимания разработчиков и, возможно, дополнительных улучшений от Microsoft для более полного учёта потребностей в работе с HTTP-соединениями и DNS.
Если ваша система сильно зависит от DNS и эффективного управления соединениями, возможно, стоит рассмотреть альтернативные подходы или даже сторонние библиотеки, которые могут предложить более гибкий и оптимизированный подход к работе с HTTP API.
Рекомендации
- Всегда тестируйте производительность вашего приложения в реальных условиях.
- Следите за обновлениями от Microsoft в отношении
HttpClient
и возможных улучшений. - Рассмотрите возможность использования паттернов повторного использования соединений или реализации собственного менеджера соединений, если это позволит достичь большей гибкости и контроля.