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

Вид: 6079|Ответ: 4

[Источник] Неправильное использование HttpClient может повредить ваше программное обеспечение

[Скопировать ссылку]
Опубликовано 14.05.2022 17:11:56 | | | |
Я годами неправильно пользовался HttpClient, но в итоге наступил кошмар. Мой сайт был нестабильным, клиенты были очень злы, и с помощью простого исправления производительность значительно улучшилась, а нестабильность исчезла.



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

Микросервисы могут быть сложной задачей. По мере добавления новых сервисов и распада монолитных приложений между сервисами появляется всё больше путей коммуникации. Существует множество вариантов связи, но HTTP — очень популярный вариант. Если микросервис построен на C# или любом другом языке .NET, скорее всего, вы уже используете HttpClient.


Проблема в том, что

Оператор using — это функция C#, которая обрабатывает одноразовые объекты. После завершения использования блока одноразовый объект (в данном случае HttpClient) выходит из сферы действия и уничтожается. Позвоните в службу утилизации и уберите используемые ресурсы. Это очень типичный шаблон в .NET, который мы используем для всего — от базы данных до flow writer. Фактически, любой объект с внешним ресурсом, который необходимо очистить, использует этот интерфейс IDisposable.

И тебя нельзя винить за то, что хочешь завернуть его в употребление. Во-первых, это считается хорошей практикой. Фактически, официальная документация Microsoft использует:


В целом, при использовании IDisposable объекта он должен быть объявлен и инстанциран в операторе use.
Во-вторых, весь код, который вы могли видеть...... В начале HttpClient будет указано использовать блок операторов использования, включая последнюю документацию ASP.NET самом сайте. То же самое говорится в статье в интернете.

Но HttpClient — это другое. Хотя он реализует интерфейс IDisposable, на самом деле это общий объект. Это значит, что за кулисами он находится в режиме реэнтранта и безопасна для потоков. Вам следует делить экземпляр HttpClient на протяжении всего срока жизни приложения, а не создавать новый экземпляр для каждой запусковой системы. HttpClient, давайте посмотрим почему.

Убедитесь сами

Вот простая программа для демонстрации HttpClient:

Это будет адресовано  http://aspnetmonsters.comОткроем 10 запросов и делаем GET, просто выводим статус кода, чтобы знать, что всё работает. Результат будет следующим:

Погоди, это ещё не всё!

Вся работа и всё это правильно для мира. Но это не так. Если мы вытащим инструмент netstat и посмотрим состояние сокета на машине, которая его запускает, мы увидим:

C:\code\socket>NETSTAT.EXE
...
  Прото-местный адрес — государство иностранного адреса
  TCP 10.211.55.6:12050 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12051 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12053 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12054 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12055 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12056 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12057 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12058 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12059 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12060 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12061 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12062 waws-prod-bay-017:http TIME_WAIT
  TCP 127.0.0.1:1695 SIMONTIMMS742B:1696 СОЗДАНО
...
Ну, это странно...... Приложение вышло из игры, но до компьютера Azure, где размещается сайт ASP.NET Monsters, всё ещё открыто множество таких соединений. Они внутриTIME_WAITстатус, что означает, что соединение с одной стороны (наше) закрыто, но мы всё ещё ждём, не поступят ли другие пакеты, так как они могли где-то задержаться в сети. Вот схема статуса TCP/IP:



Windows останется подключённым в этом состоянии 240 секунд (в соответствии с установкой [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]). В Windows есть ограничение на скорость открытия нового сокета, поэтому если у вас закончатся пулы соединений, вы можете увидеть такую ошибку:

Не удаётся подключиться к удалённому серверу
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Поиск в Google даст вам плохие советы по сокращению тайм-аутов соединения. На самом деле, при правильном запуске на сервере с HttpClient или аналогичным приложением сокращение тайм-аутов может привести к другим негативным последствиям. Нам нужно понять, что значит «правильно», и решить основную проблему, а не возиться с машинными переменными.

Почините

Если мы поделимся экземпляром HttpClient, то можем сократить отходы сокетов, повторно используя их:

Обратите внимание, что для всего приложения у нас есть только один общий экземпляр. HttpClient всё ещё работает как раньше (на самом деле немного быстрее из-за повторного использования сокета). Netstat теперь показывает только:

TCP 10.211.55.6:12254 waws-prod-bay-017:http УСТАНОВЛЕН
В производственной ситуации мое среднее количество сокетов около 4000, а пик достигает более 5000, что фактически выжимает доступные ресурсы на сервере и приводит к сбою сервиса. После внедрения изменений количество используемых соёмов сократилось с более чем 4000 до стабильно менее 400, обычно около 100.

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




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

Сделайте ваш HttpClient статичным.
Не отбрасывайте и не упаковывайте своё использование, если только вы специально не ищете конкретное поведение (например, сбой сервиса). HttpClient


сводка

Проблема с истощением гнезда, с которой мы боролись уже несколько месяцев, исчезла, и у наших клиентов есть виртуальный парад. Я не могу недооценивать, насколько неочевидна эта ошибка. За эти годы мы привыкли работать с реализованными объектами, IDisposable, и многие инструменты рефакторинга, такие как R# и CodeRush, на самом деле предупреждают вас, если вы этого не делаете. В этом случае избавление от HttpClient — неправильный подход. HttpClient реализует IDisposable и поощряет плохое поведение, к сожалению

Исходный текст:Вход по гиперссылке виден.




Предыдущий:ASP.NET Core размещает модели In-Process и Out-Of-Process в IIS
Следующий:ASP.NET Core (XV) использует HttpClient для отправки HTTP-запросов
 Хозяин| Опубликовано 14.05.2022 17:25:22 |
TCP TIME_WAIT — это обычная операция протокола TCP, то есть после последнего FIN-ACK клиент будет ждать прохождения двойного максимального времени жизни (MSL), чтобы убедиться, что удалённый TCP получит подтверждение запроса на завершение соединения. По умолчанию MSL — 2 минуты. В TIME_WAIT можно оставаться до 4 минут, что называется двумя MSL.

https://docs.microsoft.com/en-us ... t-from-netstat.html
Опубликовано 14.05.2022 22:35:22 |
Учитесь учиться
Опубликовано 19.05.2022 9:39:05 |
Это всё китайский, но я не могу понять, когда это связывают в предложениях
 Хозяин| Опубликовано 06.11.2023 7:16:05 |
тест
Отказ:
Всё программное обеспечение, программные материалы или статьи, публикуемые Code Farmer Network, предназначены исключительно для учебных и исследовательских целей; Вышеуказанный контент не должен использоваться в коммерческих или незаконных целях, иначе пользователи несут все последствия. Информация на этом сайте взята из Интернета, и споры по авторским правам не имеют отношения к этому сайту. Вы должны полностью удалить вышеуказанный контент с компьютера в течение 24 часов после загрузки. Если вам нравится программа, пожалуйста, поддержите подлинное программное обеспечение, купите регистрацию и получите лучшие подлинные услуги. Если есть нарушение, пожалуйста, свяжитесь с нами по электронной почте.

Mail To:help@itsvse.com