HttpClient GetAsync не работает случайно

Я использую.net HTTPClient для нескольких многопоточных потребителей, делая веб-запросы GetAsync к локальной службе со скоростью 127.0.0.1 один раз в секунду.

Веб-запросы выполняются в 99,9% случаев, но иногда несколько запросов (в течение 3-4 часов) застряли в GetAsyc и не будут завершены или истечет время ожидания. Запросы к одному и тому же сервисному URL / порту за тот же период времени будут работать нормально, а новые запросы будут выполняться нормально.

GetAsync запускается в режиме "забыл и забыл", когда по завершении вызывается обратный вызов для обработки результирующих проанализированных данных (поскольку он интегрирован с некоторым более старым кодом, который не использует асинхронность).

public void Execute(Action<IAsyncCommand> onCompletion)
{
    this.onAsyncCompletion = onCompletion;
    try
    {
       // do not await as this is fire and forget
       this.HandlRequestAysnc(this.Target, new StringContent(this.CommandPayload));
        return;
    }
    catch(Exception e)
    {
      //log exception
    }
 }
private async Task HandlRequestAysnc(Uri uri, StringContent stringContent)
{
    try
    {
        ConfiguredTaskAwaitable<HttpResponseMessage> request = stringContent != null ? webClient.PostAsync(uri, stringContent).ConfigureAwait(false) : webClient.GetAsync(uri).ConfigureAwait(false);
        //this will never return or timeout 1 in 10000 times
        using (HttpResponseMessage response = await request) 
        {
            if (response.IsSuccessStatusCode)
            {
                using (HttpContent content = response.Content)
                {
                    string result = await content.ReadAsStringAsync(); 
                    //handle result
                }
            }
            else
            {
             //handle failure
            }
        }
    }
    catch (Exception ex)
    {
         //log exception
    }
    if (this.onAsyncCompletion != null)
    {
        this.onAsyncCompletion(this);
    }
}

1 ответ

Одна из проблем с GetAync заключается в том, что стек TCP теперь находится под контролем, как только начинается сеанс. Недавний лабораторный эксперимент доказал, что увеличение количества запросов на получение 10000 запросов (для выяснения причин возникновения проблем с памятью в среде prod) заняло более 5 минут (после завершения приложения), чтобы стек TCP все очистил.

Если вы обнаружите, что состояние сокета имеет Fin-Wait 1 или 2, Time-Wait или другие полупериодические сеансы, это просто признак большой проблемы, когда одна из двух систем (или обе) не может обрабатывать трафик с такой скоростью., Как только это начинает происходить, вещи быстро выходят из-под контроля, поскольку обе стороны борются за поддержание сессий, но теряют ресурсы, чтобы сделать это достаточно быстро.

Решение этой проблемы заключается в том, чтобы найти другой способ увеличить пропускную способность.

Другие вопросы по тегам