Сколько сокетов можно открыть на сервере
Пробуй проверить сколько коннектов может создать.
На клиенте в js создаю массив и туда в цикле пихаю new WebSocket.
То есть открываешь страницу и она в js генерит коннекты к приложению.
1. коннекты создаются довольно медленно
2. затыкается стабильно на 191-ом коннекте и дальше будто ничего не происходит.
На сервере в javax.websocket.OnOpen после 191 подключения ничего не приходит, на клиенте в try catch ничего не падает.
Вопросы
1. куда копать, почему 190 и все?
2. как правильно проверить максимальное число подключений?
3. если число подключений ограничено, какая стратегия работы с websocket?
4. как защититься от генерации большого числа коннектов на открытом для общего доступа сайте?
Изначально вопрос возник отсюда.
Можно все делать на том же ajax и опрашивать сервер например 1 раз в сек, данные для ответа брать из кэша приложения (чтобы не лазить по каждому запросу в БД), но не уверен, что это нормальный подход и не знаю какую нагрузку можно держать при таком варианте.
Поэтому интересно посмотреть в сторону вебсокетов, чтобы не опрашивать сервер кучей сессий каждую секунду, а отправлять клиентам инфу по мере ее готовности на сервере.
65к подключений на 1 ip порт.
Но вообще, громоздить все на одну машину - странное желание. Для какого нибудь балансира/мультиплексора ресурсов особо не требуется. Проще выкинуть на отдельный аппаратный сервер уровня Arduino ))) IMHO ))) дешево, надежно и сердито.
Ты хотябы 100 вычислительных потоков попробуй запусти. У тебя от этого поплывёт CPU. И никакой более
ползеной работы этот CPU не сделает. Он будет в спинах и локах висеть на самом деле.
А если твоя задача такова что на самом деле полезной работы не делается а сокеты просто висят
(для красоты) то наверное тогда надо архитектуру приложения пересмотреть.
в этом методе ты можешь распарсить String data выделить команду и передать управление методу который соответствует этой команде и соответственно передать сами данные , а так же передать Session userSession , как правило клиенту надо ответить (что не обязательно).
а как метод/команда будет работать - это уже твоя воля.
это простой вариант.
более сложный - это когда идет рассылка по нескольким клиентам. но это отдельная тема.
в этом методе ты можешь распарсить String data выделить команду и передать управление методу который соответствует этой команде и соответственно передать сами данные , а так же передать Session userSession , как правило клиенту надо ответить (что не обязательно).
а как метод/команда будет работать - это уже твоя воля.
это простой вариант.
более сложный - это когда идет рассылка по нескольким клиентам. но это отдельная тема.
В целом от этого пока можно абстрагироваться, так как не касается сути вопроса по большому счету.
введёт в ступор тех кто будет разбираться в коде после тебя. я бы рекомендовал типа такого
и Figure figure что это?
ws понимает строковые и бинарные данные (по умолчанию) или ты используешь какой-то подпротокол?
Означает ли это, что к веб-сайту смогут подключиться только 64 000 пользователей, и если бы я хотел обслуживать больше, мне пришлось бы перейти на веб-ферму?
Привет, Дэвид, ты нашел правильный ответ на этот вопрос? 64000 TCP-соединений через один IP-адрес сервера. Вы можете модернизировать свою сеть серверов до масштабирования и поддержки более 64000.Лучший случай
Ответ на этот вопрос должен касаться только простейшей конфигурации сервера, чтобы отделиться от бесчисленных переменных и конфигураций, возможных ниже по течению.
Итак, рассмотрим следующий сценарий моего ответа:
- Нет трафика в сеансах TCP, за исключением пакетов проверки активности (в противном случае вам, очевидно, потребуется соответствующая пропускная способность сети и другие ресурсы компьютера)
- Программное обеспечение, предназначенное для использования асинхронных сокетов и программирования, а не аппаратного потока на запрос из пула. (например, IIS, Node.js, Nginx . веб-сервер [но не Apache] с программным обеспечением, разработанным для асинхронного программирования)
- Хорошая производительность / доллар CPU / Ram. Сегодня условно допустим i7 (4 ядра) с 8 ГБ ОЗУ.
- Хороший межсетевой экран / роутер под стать.
- Нет виртуального лимита / регулятора - т.е. Linux somaxconn, IIS web.config .
- Нет зависимости от другого более медленного оборудования - нет чтения с жесткого диска, потому что это будет наименьший общий знаменатель и узкое место, а не сетевой ввод-вывод.
Подробный ответ
Синхронные проекты с привязкой к потоку, как правило, хуже всего работают по сравнению с реализациями асинхронного ввода-вывода.
Хороший выбор дизайна программного обеспечения
В WebFarm?
Каким бы ни был предел для вашей конкретной ситуации, да, веб-ферма - хорошее решение для масштабирования. Для этого существует множество архитектур. Один из них использует балансировщик нагрузки (хостинг-провайдеры могут предлагать их, но даже у них есть ограничение вместе с потолком пропускной способности), но я не поддерживаю этот вариант. Для одностраничных приложений с длительными соединениями я предпочитаю вместо этого иметь открытый список серверов, которые клиентское приложение будет выбирать случайным образом при запуске и повторно использовать в течение всего жизненного цикла приложения. Это устраняет единую точку отказа (балансировщик нагрузки) и обеспечивает масштабирование через несколько центров обработки данных и, следовательно, гораздо большую пропускную способность.
Разрушая миф - 64К портов
Обновление 2019-05-30
Допустим, у меня есть Windows 7 с одним реальным сетевым интерфейсом и несколькими интерфейсами обратной связи. У меня есть сервер с поддержкой IOCP, который принимает подключения от клиентов. Я пытаюсь смоделировать как можно больше реальных клиентских подключений к серверу.
Мой клиентский код просто устанавливает X количество сокетных соединений (обратите внимание, что клиент привязывается к данному интерфейсу):
В петлевом интерфейсе у меня есть несколько IP-адресов, которые я использую для привязки. Кроме того, я также использую настоящий интерфейс для привязки. Я столкнулся с проблемой, когда количество открытых сокетов составляет около 64 КБ на машину:
Я пробовал несколько беспомощных вещей, таких как: - установка MaxUserPort на максимальное значение и некоторые другие рекомендуемые параметры TCPIP в реестре. - пытаться запустить два сервера на разных интерфейсах (реальных интерфейсах и обратной связи) и использовать несколько клиентов.
Это известное ограничение в Windows или его можно как-то преодолеть?
Спасибо за помощь!
3 ответа
На какой-то странице Microsoft я обнаружил, что:
. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort Подраздел реестра определяется как максимальный порт, до которого могут быть выделены порты для подстановочных знаков. Значение записи реестра MaxUserPort определяет динамический диапазон портов .
Итак, если я заставлю конечную точку использовать определенный порт, например
Тогда я могу открыть более 64K сокетов одновременно в системе.
В своем примере кода вы звоните Bind(bindEndpoint) , но не показываете, как bindEndpoint определено. Проверьте это:
- Ваша система фактически имеет несколько IP-адресов (обратная связь не учитывается)
- Вы фактически устанавливаете IP-адрес конечной точки на IP-адрес (не на петлю)
- Связки распределяются по нескольким IP-адресам
Адрес обратной связи не считается, потому что многие системы обрабатывают его специально для целей маршрутизации и привязки. Таким образом, привязка к портам в кольцевом шлейфе может поглощать порты по всем адресам так же, как если бы вы привязывались к INADDR_ANY ( 0.0.0.0 )
TCP и UDP используют 16-разрядное целое число без знака для обозначения номера порта. Я не думаю, что какая-либо реализация в какой-либо операционной системе сможет открыть в лучшем случае более 65535 сокетов на связанный адрес. Кроме того, я не удивлюсь, если Windows не реализует полностью изолированные таблицы состояний для каждого адаптера или каждого связанного адреса, а использует глобальную таблицу состояний. В таком случае это будет ограничение сетевой архитектуры Windows вместо мягкого настраиваемого ограничения.
32720 розетки. Я пробовал каждое известное изменение переменной, чтобы поднять этот предел. Но сервер остается ограниченным в 32720 открытом сокете, даже если есть еще 4Go свободной памяти и 80% бездействующего процессора.
Если вы имеете дело с openssl и потоками, проверьте /proc/sys/vm/max_map_count и попробуйте поднять его.
о каком сервере вы говорите ? Возможно, он имеет жестко закодированный max или работает в других пределах (max threads/out of address space и т. д.)
в IPV4 уровень TCP имеет 16 бит для порта назначения и 16 бит для порта источника.
видя, что ваш предел 32K, я ожидал бы, что вы действительно видите предел исходящих TCP-соединений, которые вы можете сделать. Вы должны иметь возможность получить максимум 65K сокетов (это будет предел протокола). Это ограничение для общего числа именованных соединений. К счастью, привязка порта для входящих подключений использует только 1. Но если вы пытаетесь проверить количество соединений с одной машины, вы можете иметь только 65K общих исходящих соединений (для TCP). Для проверки количества входящих подключений потребуется несколько компьютеров.
Примечание: Вы можете вызвать сокет (AF_INET. ) до количества доступных файловых дескрипторов, но вы не можете связать их без увеличения числа доступных портов. Чтобы увеличить диапазон, сделайте это:
Эхо "1024 65535" > /proc/sys / net/ipv4/ip_local_port_range (cat, чтобы увидеть, что у вас есть в настоящее время-по умолчанию 32768 до 61000)
возможно, пришло время для нового протокола TCP, который позволит 32 бита для исходного и dest портов? Но сколько приложений действительно нужно более 65 тысяч исходящих подключений?
следующее позволит 100 000 входящих подключений на linux mint 16 (64 бит) (вы должны запустить его как root, чтобы установить пределы)
Если вы рассматриваете приложение, где вы считаете, что вам нужно открыть тысячи сокетов, вы обязательно захотите прочитать о Проблема C10k. На этой странице обсуждаются многие проблемы, с которыми вы столкнетесь при увеличении количества клиентских подключений к одному серверу.
в Gnu+Linux максимум-это то, что вы написали. Это число (вероятно) указано где-то в стандартах сети. Сомневаюсь, что тебе нужно так много розеток. Вы должны оптимизировать способ использования сокетов, а не создавать десятки все время.
чистая/сокет.c fd выделяется в sock_alloc_fd (), который вызывает get_unused_fd ().
глядя на linux/fs / файл.c, единственное ограничение на количество fd-это sysctl_nr_open , ограниченном
и может быть прочитано с помощью sysctl fs.nr_open что дает 1M по умолчанию здесь. Так что fd, вероятно, не ваша проблема.
редактировать вы, вероятно, также проверили это, но не могли бы вы поделиться выводом
вообще иметь слишком много живых соединений-это плохо. Однако все зависит от приложения и шаблонов, с которыми оно взаимодействует со своими клиентами.
Я полагаю, что существует шаблон, когда клиенты должны быть постоянно асинхронно подключены, и это единственный способ работы распределенного решения.
Assumimg нет узких мест в памяти / cpu / сети для текущей нагрузки, и имея в виду, что оставить простое открытое соединение-единственный способ распределенные приложения потребляют меньше ресурсов (например, время подключения и общая/Пиковая память), общая производительность сети ОС может быть выше, чем использование лучших практик, которые мы все знаем.
хороший вопрос, и он нуждается в решении. Проблема в том, что никто не может на это ответить. Я бы предложил использовать технику divide & conquer, и когда узкое место будет найдено, вернитесь к нам.
пожалуйста, разберите приложение на тестовом стенде, и вы найдете узкое место.
Проверьте реальные пределы запущенного процесса.
max для nofiles определяется ядром, следующее, поскольку root увеличит max до 100 000 "файлов", т. е. 100k CC
чтобы сделать его постоянным edit/etc / sysctl.conf
затем вам нужно, чтобы сервер запрашивал больше открытых файлов, это отличается от сервера. Например, в nginx вы устанавливаете
перезагрузите nginx и проверьте /proc / / limits
чтобы проверить это, вам нужно 100 000 сокетов в вашем клиенте, вы ограничены в тестировании количеством портов в TCP на IP-адрес.
для увеличения диапазона локальных портов до максимума.
64000 портов для тестирования.
если этого недостаточно, вам нужно больше IP-адресов. При тестировании на localhost вы можете привязать источник / клиент к IP, отличному от 127.0.0.1 / localhost.
например вы можете привязать тестовые клиенты к IPs, случайным образом выбранным от 127.0.0.1 до 127.0.0.5
используя apache-bench, вы установите
сокеты Nodejs будут использовать
/ etc / security / limits.conf настраивает PAM: обычно это не имеет значения для сервера.
если сервер проксирует запросы, используя TCP, например, upstream или mod_proxy, сервер ограничен ip_local_port_range. Это легко может быть предел 32,000.
Читайте также: