Java Socket Programming не работает для 10000 клиентов

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

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

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

9 ответов

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

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

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

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

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

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

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

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

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

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

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

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

Это не простой вопрос, но для очень глубокого ответа (извините, но не в java), посмотрите это: http://www.kegel.com/c10k.html


РЕДАКТИРОВАТЬ

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

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

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

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

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

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

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

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

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

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

  3. Что-то другое? Почини это.

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

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

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

Другие вопросы по тегам