Java Socket Programming не работает для 10 000 клиентов - PullRequest
8 голосов
/ 31 марта 2009

Я могу создать несколько потоков для поддержки функции нескольких клиентов в программировании сокетов; это работает нормально. Но если 10 000 клиентов хотят подключиться, мой сервер не может создать столько потоков.

Как мне управлять потоками, чтобы я мог слушать всех этих клиентов одновременно?

Кроме того, если в этом случае сервер хочет отправить что-то конкретному клиенту, то как это возможно?

Ответы [ 9 ]

11 голосов
/ 31 марта 2009

Вы должны исследовать библиотеку Java NIO ("New I / O") для неблокирующего сетевого программирования. NIO был разработан для решения точно проблемы масштабируемости сервера, с которой вы столкнулись!

7 голосов
/ 31 марта 2009

Для масштабируемого программирования сокетов в Java требуются выбираемые каналы , предоставляемые в пакетах "New I / O" или NIO. Используя неблокирующий ввод-вывод, один поток может обслуживать множество сокетов, обслуживая только те сокеты, которые готовы.

Одним из наиболее масштабируемых приложений NIO с открытым исходным кодом является Grizzly компонент сервера приложений Glassfish. Жан-Франсуа Арканд написал ряд информативных, подробных постов в блоге о своей работе над проектом и освещает многие тонкие ловушки при написании такого рода программного обеспечения с помощью NIO.

Если концепция неблокирующего ввода-вывода является для вас новой, использование существующего программного обеспечения, такого как Grizzly, или, по крайней мере, использование его в качестве отправной точки для вашей адаптации, может быть очень полезным.

6 голосов
/ 31 марта 2009

Преимущества NIO спорны. См. Записи блога Пола Тима здесь и здесь .

4 голосов
/ 31 марта 2009

Модель с резьбой на соединение (Blocking Socket I / O) не будет хорошо масштабироваться. Вот введение в Java NIO, которое позволит вам использовать неблокирующие вызовы сокетов в Java: http://today.java.net/cs/user/print/a/350

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

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

Как уже упоминалось, 10.000 клиентов не легко. Для java NIO (возможно, дополненный отдельным пулом потоков для обработки каждого запроса без блокировки потока NIO) является обычным способом обработки большого количества клиентов.

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

Тем не менее, NIO, как известно, трудно получить 100% правильно, когда вы в первый раз его внедрите.

Я бы порекомендовал либо попробовать, либо хотя бы посмотреть на источник для библиотеки Naga NIO по адресу naga.googlecode.com . База кода для библиотеки мала по сравнению с большинством других платформ NIO. Вы сможете быстро выполнить тест, чтобы увидеть, сможете ли вы запустить и запустить 10.000 клиентов.

(Источник Naga также может быть свободно модифицирован или скопирован без указания автора)

1 голос
/ 31 марта 2009

Почему бы вам не обработать только определенное количество запросов одновременно.

Допустим, вы хотите обрабатывать максимум 50 запросов одновременно (чтобы не создавать слишком много потоков)

Вы создаете пул из 50 потоков.

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

Это должно масштабироваться легче.

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

1 голос
/ 31 марта 2009

Это не простой вопрос, но для очень глубокого ответа (извините, но не в java) смотрите это:


EDIT

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

0 голосов
/ 24 марта 2012

Вы должны выяснить, почему ваше приложение не работает на 10000 потоков.

  1. Есть ли жесткое ограничение на количество потоков в JVM или ОС? Если да, можно ли его отменить?

  2. Вам не хватает памяти? Попробуйте настроить меньший размер стека для потока и / или добавить больше памяти на сервер.

  3. Что-то еще? Исправьте это.

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

Вы также можете рассмотреть NIO, но я думаю, что он также может нормально работать с потоками.

0 голосов
/ 02 июля 2009

Лично я предпочел бы создать настраиваемую неблокирующую настройку ввода / вывода, например, использовать один поток для приема клиентов и использовать другой поток для их обработки (проверка доступности любого ввода и запись данных в выходной файл при необходимости) .

...