Как держать больше 65535 одновременных TCP соединений?

Хочется одним сервером держать около 150к одновременных WebSocket подключений.

Вдохновился постом про 600к одновременных подключений на Amazon EC2, и постом про нагрузочное тестирование WebSocket'ов Tsung'ом.

Читал, теоретический лимит 65535 – это с одного IP на один IP, порт. Тут подключаться будут с разных IP.

Пробую тестировать на DigitalOcean. Поднял сервер, запустил простейший WS сервер на Swoole, установил Tsung для нагрузочного тестирования.

Поднимаю ещё 3 VPS в качестве «рабочих» – будут бомбить сервер соединениями. Несколько – чтобы с нескольких разных IP.

Но во всех тестах наибольшее число одновременных было всего 65526 – это когда все рабочие были в этом же регионе DigitalOcean. Второй раз попробовал запускать каждого рабочего в отедльном регионе – стало только хуже: около 56к. В остальном отваливались с ошибкой EADDRINUSE.

Где тут узкое место? Сеть DO как-то ограничнивает число подключений к одной виртуалке?
  • Вопрос задан
  • 1321 просмотр
Пригласить эксперта
Ответы на вопрос 6
@pfg21
ex-турист
количество соединений на один порт ограничивается только возможностями системы.
ограничение 65 536 это про общее количество портов на систему, к количеству соединений отношения не имеет.

чтобы узнать условия предоставления тебе ресурсов надо почитать условия договора или условия тарифа, на основе которого тебе дают компутерные мощности.
Ответ написан
В случае входящих соединений, очевидного лимита в 65535 соединений нет, скорей всего вы упретесь в лимит на файловые дискрипторы (сокеты), для каждого соединения нужен сокет. При этом лимиты могут быть на уровне пользовательских лимитов (и надо учесть для сервисов запускаемых через systemd действуют отдельные лимиты, а не те, которые указываются в limits.conf). Обычно по умолчаню лимиты дискрипторов в районе 1024-4096, существенно ниже 65535. Для очень большого количества сокетов необходимо будет так же менять sysctl на максимальное число открытых файлов, а возможно и пересобирать ядро, чтобы обойти заложенные верхние ограничения.

В случае исходящих соединений, вы кроме сокетов упретесь в нехватку эфемерных портов, для каждого исходящего соединения требуется отдельный эфемерный порт. По умолчанию, их в районе 16k и можно расширить до 63k через соответствующие sysctl. Выше этого значения разрешить нехватку портов можно путем добавления дополнительных IP + в зависимости от системы, может потребоваться установка флагов SO_REUSEADDR/SO_REUSEPORT/SO_PORT_SCALABILITY). Как они действуют, и какие комбинации надо использовать зависит не только от системы,но и от версии ядра, попытка разобрать есть здесь:
https://stackoverflow.com/questions/14388706/socke...
Но в случае, если исходящий трафик идет через NAT (в случае виртуализации это почти всегда так), необходимо решать аналогичную проблему на уровне NAT.

Для очень большого количества соединений вы будете упираться и в другие лимиты - sysbuf'ы, память и другие.
Ответ написан
@galaxy
Поднимаю ещё несколько VPS'ок в качестве «рабочих»

Несколько - это сколько?
Есть такой sysctl параметер, как net.ipv4.ip_local_port_range - диапазон портов для клиентских соединений (из этого пула присваиваются порты при открытии нового соединение, в котором машина выступает как клиент). По умолчанию он выглядит как-то так: 32768 60999 (т.е. чуть больше 28к доступных портов). Т.е. два рабочих без настройки 150к коннектов никак не сделают (даже с настройкой, т.к. лимит исходящих соединений к одному IP - 65535).

Еще есть несколько параметров, которые влияют на очередь обработки исходящих и входящих соединений. Почитать про них и их настройку можно тут (англ) и тут (рус).
Ну и в статьях, на которые вы сами даете ссылки, есть рекомендации по настройке некоторых параметров (например, ограничения числа файловых дескрипторов).
Ответ написан
firedragon
@firedragon
Senior .NET developer
4 ip в балансировку и держите себе.
Ответ написан
msHack
@msHack
На количество коннектов ограничений нет Это Количество портов 1-65535 ограничения могут быть в роутере,у провайдера,и в операционной системе к примеру процессор и оперативная память роутера не всегда спровляются и с 5000 соединений
Ответ написан
xenon
@xenon
Too drunk to fsck
Вы говорите об ограничении в 64k портов. Оно проявляется, например, в том, что вы не сможете на сервере запустить (на одном IP) больше 64k сетевых сервисов. (ssh слушает порт 22, apache слушает 80, mysql слушает 3306) итд. Каждый слушающий сервис идентифицируется по сокету ( IP + порт), IP у вас один, портов 64k, значит, 64k слушающих сокетов.

А вот для установленных TCP соединений:

socket
An address which specifically includes a port identifier, that
is, the concatenation of an Internet Address with a TCP port.

connection
A logical communication path identified by a pair of sockets.

https://tools.ietf.org/html/rfc793

То есть, соединение идентифицируется по IP сервера, порт сервера, IP клиента, порт клиента.

Да и вы сами на любом более-менее активном веб-сервере видите через lsof множество соединений, и они все установлены с одним вашим сокетом (IP:80 или IP:443), но у них разный второй сокет. Если пользователь, например, качает какой-то файл в два потока, будет один коннект: server:80 - client:4444 и еще один коннект: server:80 - client:4445. Это разные TCP соединения.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы