Увеличение активности обмена данными между микросервисами зачастую является проблемой в архитектуре современных IT решений. Выжать максимум и выжить любой ценой — серьёзный вызов для любой разработки. Поэтому поиск оптимальных решений — это не прекращающийся процесс. В статье кратко изложены проблемы, которые могут возникнуть при высоконагруженном использовании http запросов и пути их обхода.  Эта история начинается с ошибки. Как-то мы проводили нагрузочное тестирование, основным элементом которого было выполнение большого количества коротких http запросов. Клиент, написаный под netcore 2.2, начиная с какого-то момента, выдавал System.Net.Sockets.SocketException: Address already in use. Достаточно быстро выяснилось, что на клиенте не успевали освобождаться порты, и в какой-то момент система получала отказ в открытии нового. Теперь, если перейти к коду, проблема была в использовании старого подхода с классом HttpWebRequest и конструкции: Казалось бы, мы высвобождаем ресурс, и порт должен быть освобожден своевременно. Однако netstat сигнализировал о быстром росте количества портов в состоянии TIME_WAIT. Это состояние означает ожидание закрытия соединения (и возможно получение потерянных данных). Как следствие порт может находится в нем 1-2 минуты. Данная проблема рассмотрена довольно подробно во многих статьях (Проблемы с очередью TIME_WAIT, История о TIME_WAIT). Все же это означает, что dotnet «честно» пытается закрыть соединение, а дальнейшее происходит уже по вине настроек таймаута в системе. Не буду рассказывать про keep-alive. Об этом можно почитать самостоятельно. Целью статьи является попытка обойти грабли, заботливо разложенные на пути разработчика. Согласно msdn, свойство KeepAlive класса HttpWebRequest по умолчанию равно true. То есть все это время HttpWebRequest «обманывал» сервер, предлагая ему поддержать соединение, после чего сам же его разрывал. Если быть точнее, HttpWebRequest с настройками по умолчанию не отправлял заголовок «Connection: keep-alive», просто этот режим подразумевается в стандарте HTTP/1.1. Первое, что следовало попробовать, это принудительно отключить KeepAlive. Если установить HttpWebRequest.KeepAlive = false, то в запросе появляется заголовок «Connection: close». Надо признать, что на тестовом стенде это полностью решило проблему. В качестве сервера был настроен nginx со статической страницей.  Тестировался следующий код: Однако при попытке запустится на серверном железе, при больших нагрузках (свыше 1000 запросов в секунду) этот код вновь начал выдавать те же ошибки. Только теперь порты находились в состоянии CLOSE_WAIT, LAST_ACK. Это пред-финальные состояния закрытия соединения, когда клиент ждет подтверждение от инициатора закрытия. Такое поведение сигнализирует о том, что клиент начинает «захлебываться» вновь открываемыми соединениями. Действительно, чтобы добиться максимальной производительности, соединение нужно переиспользовать. Для этого необходимо включить режим keep-alive и взять класс HttpClient. Как именно он работает и как лучше его использовать стоит почитать здесь и здесь. Другой вопрос заключается в том, как убедится, что соединения переиспользуются? Существование одного keep-alive соединения регулируется двумя основными параметрами на сервере nginx: Если просматривать соединения в netstat или wireshark, то при больших нагрузках открытые порты на клиенте также будут стремительно меняться. Только выставив keepalive_requests в большие значения (> 1000) можно увидеть, что все работает как надо. Если вы не используете http запросы в высоконагруженном режиме, то вам подойдет любой вариант. Вряд ли вы успеете исчерпать все порты. Если же в вашем приложении переиспользовать соединения смысла нет, например вы редко повторно обращаетесь к серверу, то стоит сознательно отключать keep-alive. Также keep-alive стоит использовать правильно и с осторожностью при большом потоке запросов, регулируя время жизни соединения в зависимости от частоты повторных обращений к серверу. И напоследок немного тестовых сравнений производительности: Сервер nginx настроен с параметрами:  Математик. Системный программист.