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

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

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

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

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);
    }
}

person Grant G    schedule 22.05.2015    source источник
comment
Здесь все хорошо. Может быть, удаленный сервер просто не отвечает? Установите тайм-аут и убедитесь, что он работает. Подтвердите мне, что вы проверили тайм-аут.   -  person usr    schedule 22.05.2015
comment
Я проверил тайм-аут, во время тестирования он работает правильно. Я могу заблокировать свою службу с помощью точки останова и получу тайм-аут в моем коде .net. HTTPClient настроен следующим образом: private HttpClient webClient = новый HttpClient (новый HttpClientHandler () {AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip}) {MaxResponseContentBufferSize = 10000000, Timeout = TimeSpan.From};   -  person Grant G    schedule 23.05.2015
comment
Вы используете результат или ожидание где-нибудь в приложении?   -  person usr    schedule 23.05.2015
comment
Нет - задача никогда не ожидается, и мы никогда не получаем доступ к Результату. Мы попытались найти состояние тупика, но, похоже, его не существует. Это также, кажется, происходит каждые 10000 или около того запросов ...   -  person Grant G    schedule 23.05.2015
comment
Мы закончили тем, что добавили код для проверки запущенных задач (которые теперь принимают токен отмены) и отменили их, если они застряли слишком долго. Кажется, это работает, поскольку GetAsync вернется ... Хотя я все же хотел бы разобраться в этом.   -  person Grant G    schedule 23.05.2015


Ответы (1)


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

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

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

person JWP    schedule 09.09.2015