TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.76K subscribers
Post #1401 1.74K
День 1135. #ЗаметкиНаПолях
Избегаем Проблем с DNS в HttpClient
HttpClient позволяет отправлять HTTP-запросы. Подразумевается, что он создаётся однократно и повторно используется на протяжении всего жизненного цикла приложения. HttpClient имеет пул для повторного использования соединений. Если вы отправите несколько запросов на один и тот же хост, они будут повторно использовать одно и то же соединение. Таким образом, приложение экономит доступные ему сокеты. Кроме того, это повышает производительность приложения, избегая рукопожатий TCP и TLS для каждого запроса к одному и тому же хосту.

Сохранение соединений открытыми - хорошо с точки зрения производительности, но вы должны быть осторожны, чтобы не хранить устаревшие соединения. Если срок жизни DNS истёк, хост может изменить свой IP-адрес. В этом случае открытые соединения должны быть закрыты. HttpClient не делает этого автоматически, поскольку ему ничего не известно о сроке жизни DNS.

Когда происходит изменение DNS?
- При сине-зелёном развёртывании (в Azure, когда вы выполняете развёртывание в промежуточном слоте, а затем переключаете рабочий/промежуточный слоты).
- При изменении настроек в диспетчере трафика Azure.
- В случае отказа основного сервера и перехода на бекап и т.п.

Чтобы исправить эту проблему, вы можете указать время ожидания для автоматического закрытия соединения. SocketsHttpHandler используется для настройки поведения HttpClient и его пула соединений. Необходимо настроить 2 свойства:
- PooledConnectionIdleTimeout,
- PooledConnectionLifetime.
Эти свойства заставляют HttpClient закрыть соединение через определённое время. Таким образом, следующий запрос к тому же хосту должен будет открыть новое соединение и использовать новый DNS или другие изменения в сети.

По умолчанию простаивающие соединения закрываются через 1 минуту. Однако активные соединения никогда не закрываются. Вы должны явно установить для PooledConnectionLifetime желаемое значение.
using System.Threading;
using System.Net.Http;

using var handler = new SocketsHttpHandler()
{
// Максимальное время простоя соединения в пуле. Если в течение этого времени нет запросов, соединение разрывается. По умолчанию: 1 минута
PooledConnectionIdleTimeout =
TimeSpan.FromMinutes(1),

// Максимальное время жизни соединения в пуле, независимо от активности. Периодически соединение пересоздаётся для обновления DNS или других сетевых изменений. По умолчанию: никогда.
PooledConnectionLifetime =
TimeSpan.FromMinutes(1)
};

using var client = new HttpClient(handler);

var timer = new PeriodicTimer(
TimeSpan.FromSeconds(10));

while (await timer.WaitForNextTickAsync())
{
_ = await client
.GetStringAsync("https://www.google.com");
}

Замечание: Другой способ избежать проблем с изменённым DNS – использовать IHttpClientFactory:
services
.AddHttpClient<IMyService, MyService>()
.SetHandlerLifetime(TimeSpan.FromMinutes(1));

Источник: https://www.meziantou.net/avoid-dns-issues-with-httpclient-in-dotnet.htm
  • 👍 6
More from @netdeveloperdiary
  1. Oct 15, 2026Post #3374
  2. Oct 14, 2026Post #3373
  3. Oct 13, 2026День 2813. #ЗаметкиНаПолях #Async Ещё Раз Про Async/Await в C#. Часть 1 Почему существует…
  4. Oct 12, 2026День 2812. #Карьера #AI Как Разработчикам Оставаться Полезными, Когда Код Пишет ИИ? По мер…
  5. Oct 11, 2026День 2811. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  6. Oct 10, 2026День 2810. #ЧтоНовенького #VSCode Более Быстрый и Лёгкий C# Dev Kit Мы, разработчики, люби…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →