После более чем 1000 успешных вызовов получаем сообщение «Существующее соединение было принудительно закрыто»

#.net #.net-core #dotnet-httpclient #.net-standard-2.0

#.net #.net-core #dotnet-httpclient #.net-стандарт-2.0

Вопрос:

Я провожу некоторое нагрузочное тестирование клиентского и серверного кода. По ходу работы первые 1000 вызовов проходят просто отлично. Но (при некоторых запусках) я начинаю получать следующее исключение:

 System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.  
---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host..  
---> System.Net.Sockets.SocketException (10054): An existing connection was forcibly closed by the remote host.
  

Некоторые поисковые запросы показывают, что распространенным решением является добавление следующего кода:

 System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
  

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

Моя настоящая цель запроса заключается в том, что после того, как это начнет происходить, я получаю множество сбоев того же рода.

Мне интересно, находится ли мой HttpClient в сбойном состоянии после того, как это произойдет? Если это так, как мне это исправить? (Мой HttpClient является статическим, и если он завершится неудачей, то все мои вызовы завершатся неудачей.)

Примечание: Мой код выполняется как NuGet, который должен выполняться в .Net Framework 4.7 и .Net Core 3.1.

Комментарии:

1. Убедитесь, что вы используете SendAsync метод на HttpClient , никогда не используйте GetAsync , PostAsync … никогда не изменяйте Default... свойства при совместном использовании HttpClient между многими одновременными запросами.

2. @Andy — Я использую PostAsync. Почему это плохо?

3. Я использую SendAsync строго потому, что мне нравится, чтобы у каждого запроса был свой собственный словарь заголовков. Таким образом, если что-то изменит Default... свойства, это не повлияет на ваши вызовы. Вы не удаляете свой HttpClient и не переназначаете его каждый раз, верно? Возможно, это глупый вопрос, но, клянусь, я видел это раньше, и это было потому, что кто-то использовал несколько HttpClients или каждый раз удалял / переназначал их.

4. @Энди — Я понимаю твои рассуждения. My HttpClient — это статический объект, который выделяется в «статическое время» и существует в течение всего срока действия приложения. В этом причина моего вопроса. Я хочу знать, может ли соединение для HttpClient перейти в состояние сбоя, и мне нужно очистить и создать новое.

5. @andy — это связанная, но другая проблема. Я опубликовал ответ, который, как я полагаю, помог нам решить эту проблему.

Ответ №1:

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

Ответ №2:

Я полагаю, что эта проблема возникла из-за того, что WSO2 API Manager ограничил количество подключений. Мы изменили некоторые настройки на серверах WSO2, и эта проблема исчезла. (Я не знаю изменений, поскольку их внес администратор WSO2.)