Программирование сокетов веб-сервера

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

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


person Ashwini Verma    schedule 28.07.2013    source источник


Ответы (3)


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

Как правило, если вы делаете это на Java, вам не следует использовать стандартный блокирующий java.io API, потому что он задействует два потока на каждое отдельное соединение: один для чтения, один для записи. Вместо этого используйте библиотеку Netty, которая обеспечивает асинхронную связь TCP, а это означает, что только пул потоков небольшого размера может обрабатывать очень большое количество запросов: потоки никогда не простаивают, ожидая получения ввода или отправки вывода. Они заняты только обработкой данных.

person Marko Topolnik    schedule 28.07.2013
comment
Библиотека java.net не «задействует два потока на ... соединение». Это был бы выбор дизайна приложения. Злоупотребляя available() в соответствующих обстоятельствах, можно было бы использовать один поток для всех соединений, хотя это нелепо. Количество принятых подключений может исчисляться сотнями тысяч на соответствующем оборудовании. - person user207421; 29.07.2013
comment
Это было бы больше, чем выбор приложения, это был бы обычный способ работы с блокирующим API. Кстати, я не сказал (и не имел в виду), что это библиотека java.net, которая задействует 2 потока на соединение, - person Marko Topolnik; 29.07.2013
comment
Я сказал, что это делает его использование. Я также совершенно уверен, что различия не нуждались в уточнении. - person Marko Topolnik; 29.07.2013

Я написал для себя небольшой чат-сервер (который в основном делает то же самое).

Дизайн, который я выбрал, был первым потоком, который принимает соединения (в основном цикл while, повторяющий accept() на экземпляре объекта ServerSocket). Этот поток - listening to соединения.

И для каждого соединения, возвращаемого accept(), я запускал отдельный поток, который обрабатывает и reads from это соединение. Все ссылки на эти потоки хранились в синхронизированном List для дальнейшей обработки, например, закрытия соединения позже и так далее.

person Maxime Piraux    schedule 28.07.2013

Вы объединяете «слушать» и «читать». Это не одно и то же. «Слушать» означает, что сервер создает прослушивающий сокет, из которого могут приниматься соединения в большом количестве. Каждое из этих соединений затем читается и записывается.

person user207421    schedule 28.07.2013