Есть ли ограничение на количество соединений tcp / ip между машинами в Linux? - PullRequest
24 голосов
/ 17 апреля 2009

У меня есть очень простая программа, написанная за 5 минут, которая открывает сокет-сервер и перебирает запрос и выводит на экран отправленные ему байты.

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

На другой машине (где сеть между ними не насыщена) я создал простую программу, которая зацикливается и подключается к серверу машины и отправляет байты "hello world".

Когда цикл 1000-3000, клиент завершает все отправленные запросы. Когда цикл выходит за пределы 5000, он начинает иметь тайм-ауты после завершения первого числа запросов X. Почему это? Я удостоверился, чтобы закрыть мою розетку в цикле.

Можете ли вы создать столько соединений в течение определенного периода времени?

Применяется ли этот предел только для одних и тех же машин, и мне не нужно беспокоиться об этом на производстве, когда более 5000 запросов поступают с разных машин?

Ответы [ 6 ]

26 голосов
/ 17 апреля 2009

Есть ограничение, да. Смотри ulimit.

Также необходимо учитывать состояние TIMED_WAIT. После закрытия сокета TCP (по умолчанию) порт остается занятым в состоянии TIMED_WAIT в течение 2 минут. Это значение настраивается. Это также «выгонит вас из сокетов», даже если они закрыты.

Запустите netstat, чтобы увидеть TIMED_WAIT в действии.

P.S. Причина TIMED_WAIT состоит в том, чтобы обрабатывать случай пакетов, прибывающих после закрытия сокета. Это может произойти, потому что пакеты задержаны или другая сторона просто не знает, что сокет еще не закрыт. Это позволяет ОС молча отбрасывать эти пакеты без шанса «заразить» другое, не связанное с сокетом соединение.

8 голосов
/ 17 апреля 2009

При поиске максимальной производительности вы сталкиваетесь со множеством проблем и потенциальных узких мест. Выполнение простого теста Hello World не обязательно найдет их всех.

Возможные ограничения включают:

  • Ограничения сокета ядра: посмотрите в /proc/sys/net множество настроек ядра ..
  • лимиты процесса: проверьте ulimit, как другие заявили здесь
  • По мере усложнения вашего приложения оно может не иметь достаточной мощности ЦП, чтобы соответствовать количеству входящих подключений. Используйте top, чтобы проверить, не превышен ли ваш ЦП
  • количество потоков? У меня нет опыта работы с потоками, но это может вступить в игру вместе с предыдущими предметами.
2 голосов
/ 28 декабря 2016

Быстрый ответ: 2 ^ 16 портов TCP, 64 КБ.

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

Внутренние последствия для TCP не очень понятны (для меня). Каждый порт требует памяти для своего создания, входит в список и нуждается в сетевых буферах для передаваемых данных.

При 64-битных сеансах TCP издержки для экземпляров портов могут быть проблемой на 32-битном ядре, но не на 64-битном ядре (исправление здесь с радостью принято). Процесс поиска с сеансами 64 КБ может немного замедлить работу, и каждый пакет попадает в очереди таймера, что также может быть проблематичным. Хранилище для транзитных данных теоретически может увеличиваться до размеров окна, умноженного на порты (возможно, 8 ГБ).

Вероятно, вы видите проблему со скоростью соединения (упомянутой выше). TCP обычно требует времени, чтобы что-то делать. Однако это не обязательно. TCP-соединение, транзакция и отключение могут быть выполнены очень эффективно (проверьте, как сеансы TCP создаются и закрываются).

Существуют системы, которые передают десятки гигабит в секунду, поэтому масштабирование на уровне пакетов должно быть в порядке.

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

Производительность системы, если она тщательно настроена, должна быть в порядке.

Серверная часть вещей должна масштабироваться аналогичным образом.

Я был бы обеспокоен такими вещами, как пропускная способность памяти.

Рассмотрим эксперимент, в котором вы входите на локальный хост 10000 раз. Затем введите символ. Весь стек через пользовательское пространство будет задействован для каждого символа. Активная зона обслуживания, вероятно, превысит размер кэша данных. Работа с большим количеством памяти может привести к нагрузке на систему ВМ. Стоимость переключения контекста может приближаться к секунде!

Это обсуждается во множестве других тем: https://serverfault.com/questions/69524/im-designing-a-system-to-handle-10000-tcp-connections-per-second-what-problems

2 голосов
/ 17 апреля 2009

Ваш сервер однопоточный? Если да, то какую функцию опроса / мультиплексирования вы используете?

Использование select () не работает за пределами жестко заданного максимального предела дескриптора файла, установленного во время компиляции, что безнадежно (обычно 256 или несколько).

poll () лучше, но вы столкнетесь с проблемой масштабируемости с большим количеством FD, повторно заполняющих набор каждый раз вокруг цикла.

epoll () должен работать до некоторого другого лимита, который вы достигли.

10 тыс. Соединений должно быть достаточно простым для достижения. Используйте недавнее (ish) ядро ​​2.6.

Сколько клиентских машин вы использовали? Вы уверены, что не достигли лимита на стороне клиента?

1 голос
/ 17 апреля 2009

Да, предел установлен ядром; проверьте эту тему о переполнении стека для получения более подробной информации: Увеличение максимального количества соединений TCP / IP в Linux

1 голос
/ 17 апреля 2009

Вы можете проверить /etc/security/limits.conf

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...