Комментарии 27
Типа если уж принимать миллионы клиентов — можно и заточиться под конкретное железо и ос, и тут jvm скорее мешает чем помогает, а мак очевидно не лучший выбор по итогам тестов :)
Что-то мне не кажется, что это "круто". Это такой приём "распространено заблуждение что ...", и дальше идёт его опровержение. А на самом деле это заблуждение не так уж и распространено.
Вот 12 миллионов сокетов: https://habr.com/ru/post/460847/
Можно и 20 ... Весь вопрос в ресурсах (ЦПУ/ОЗУ).
Какая-то очень странная тут задача у автора. Если он хотел обеспечить обработку максимума сокетов, то добро пожаловать в обработку сырых TCP ... и это не так страшно. Можно сделать хоть миллион, а можно хоть и миллиард сокетов, но дело тут не в количестве, а в качестве обслуживания. Если компания ставит задачей обработку такого числа подключений, то возникает вопрос: "За какое время будет обработан тот или иной запрос?" Скажем если у автора даже NMI операции движения мышки уже испытывали голодание, то говорить о разумном времени обслуживания - нет смысла. Я все это к тому, что изначально нет вопроса в количестве сокетов и подключений, а стоит вопрос именно в эффективности. И конечно когда мы докатились до эффективности, то вопрос каким образом тут оказалось macOS и Java? Эти инструменты вообще про красоту и лень программиста (разумный баланс цена/время). Я все к тому, что важно наверное сначала верно обозначать решаемый вопрос - перед какими-то титаническими подвигами в детских песочницах.
Можно конечно и заточиться, но если ты стартап с непроверенной гипотезой и сомнительным финансированием - ты хочешь писать быстро в прототипном стиле силами двух с половиной человек, а потом магически отмасштабировать решение на миллионы пользователей.
И это я сейчас про whatsapp + erlang | discord + elixir, подозрительно одинаковые истории успеха. И ВМ там очень помогла.
The Secret To 10 Million Concurrent Connections
Теоретический предел немного меньше указанного. Портов не 65536, а только 65535, потому что нулевого порта нет.
Кроме того, если доверить операционной системе выбор клиентского порта, то Windows выбирает только номера, начиная с 1024.
В коде для эксперимента connectionsPerAddress по умолчанию 5000, а не 65536 и даже не 65535
Кстати, а в Linux клиентский порт и вовсе с 32768 начинается:
~ $ sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 32768 60999
В разных операционных системах диапазон портов разный:
для window dynamic port range: 49152-65535 для post-vista (https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/default-dynamic-port-range-tcpip-chang), xp - 1025-5000.
Кроме того, если доверить операционной системе выбор клиентского порта, то Windows выбирает только номера, начиная с 1024.
Старая информация, верная только для Windows NT/2K/XP/2K3
An IPv6 address consists of 128 bits.
Было уже раньше, на Хабре тоже (целый цикл): https://habr.com/ru/post/212885/
Немного непонятны некоторые моменты.
Если сервер и клиенты на одной машине, зачем 10.* подсеть, чем 127.* не устроила?
Если суть поставить рекорд, то стоило уменьшить до минимума буферы под TCP, а на стороне сервера увеличить backlog очередь соединений до максимума.
Интересно, сколько сможет пройти соединений через NAT. Около 65к?
Сколько в настройках conntrack сделаете, столько и будет. Больше миллиона записей conntrack точно выдерживает.
Спасибо за статью, очень интересно!
Hidden text
серию фальшивых адресов замыкания на себя (loopback address)
Я чаще наталкивался на вариант перевода "петлевой интерфейс" или "петлевой адрес".
На самом деле проблема нехватки портов обычно касается апстримов у проксирующих серверов (собственно, исходящие соединения). На практике "открытый порт" - это фикция ОС, формализм в её базе. Сколько можно реалистично обслуживать соединений? Чаще всего этот показатель ограничен числом pps, которые может обработать сетевой стек (последний раз, когда я серьёзно занимался бенчмарками - около миллиона на сетевую карту, наверное, сейчас больше).
Смешались кони и люди, а потом распутались :).
Изначально перепутаны понятия "сокет" (суть дескриптор соединения) и "порт", на чём и построена интрига.
Всю статью можно уместить в пару абзацев:
"Клиент в сторону одной пары server ip:port с одного IP может открыть до 65535 tcp-соединений, с той стороны они потребуют 65535 сокетов, которых можно завести - на сколько памяти и проца хватит. Ибо в tcp-пакетах прописана пары (изменяемый) client IP/port и (неизменный) server ip/port. Кому хочется большего - делает NAT с помощью пула адресов и соединяется с пулом адресов сервера. Хочется странного - можете делать свой протокол поверх UDP или вообще свой протокол.
Обработать дофигища входящих подключений - можно, если у сервера достаточно памяти и проца, и в ОС возможно задать нужные лимиты по сокетам и прочим дескрипторам, но иногда это потребует усилий мозгом - если нужно это сделать быстро."
У меня сервера на RHEL с 64GB оперативы начинают уходить в себя при ~14500 входящих сессий TWAMP (perfSONAR). Каждая сессия резервирует ~4KB виртуальной памяти. Много ковырял всякие конфиги но ничего внятного добиться не смог. Так что считаю перечитаю несколько раз. Если у кого-то есть готовый рецепт, буду весьма благодарен.
Спустя несколько секунд после начала эксперимента операционная система решила задействовать swap, хотя у меня ещё была память.
Это нормальное поведение. Регулируется с помощью параметра vm.swappiness
в файле /etc/sysctl.conf (после сохранения надо перезагрузиться). Он определяет процент оставшейся свободной оперативной памяти, при котором начинается задействоваться swap. Текущее значение этого параметра можно посмотреть с помощью команды cat /proc/sys/vm/swappiness.
Не совсем
vm.swappiness
определяет баланс между файловыми и анонимными страницами, что системе предпочтительнее высвобождать
Если система решит, что оптимальнее будет скинуть что-то в своп вместо сброса файловых кешей, то она имеет полное право так сделать
Вот тут есть перевод классной статьи, где очень подробно разбирается механизм работы swap
Миллион одновременных соединений