Существует ли ограничение на количество соединений tcp/ip между машинами в Linux?

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

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

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

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

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

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

Ответ 1

Есть предел, да. См. ulimit.

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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

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

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

Ответ 4

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

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

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

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

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

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

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

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

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

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

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

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

Ответ 5

Возможно, вы захотите проверить/etc/security/limits.conf