Подтвердить что ты не робот

В чем разница между Tomcat BIO Connector и NIO Connector?

Я хотел бы знать внутренности разъема NIO tomcat. Как точно используются потоки, когда мы создаем сервлет, который реализует CometProcessor? Является ли он еще одним потоком для каждого соединения?

Из того, что я читаю, разговор идет следующим образом

  • Клиент подключается к сервлету

  • Сервлет зависает до соединения, пока не будут доступны какие-либо данные к подключенному клиенту

  • Когда данные готовы, сервер записывает на httpResponse и сбрасывает его. Это фактически отключает соединение?

  • Клиент отправляет другой запрос, который сервер снова зависает.

Сколько потоков используется, когда это происходит?

4b9b3361

Ответ 1

NIO и Comet полностью не связаны: вы можете смешивать и сопоставлять их.

Использование разъема NIO (или APR в этом случае) позволяет обрабатывать больше запросов с меньшим количеством потоков из-за модели потоковой передачи. См. http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#Connector_Comparison для сравнения между соединителями.

Comet (и Websocket) имеют совершенно другую модель диспетчеризации, которая требует другой архитектуры приложения и обеспечивает более высокую пропускную способность по-другому.

Сценарий, который вы задаете в своем вопросе, является типичной блокировкой модели с одним потоком за запрос. На шаге 4 соединитель Java BIO (который по умолчанию работает через Tomcat 7) будет продолжать ждать дополнительных запросов на существующий соединитель - для HTTP-запросов keepalive. Если клиент не устанавливает Connection:close в предыдущем запросе и не закрывает соединение, поток будет зависать до тех пор, пока не будет достигнут тайм-аут keepalive. Если вы используете разъем NIO, поток будет возвращаться в пул потоков сразу после отправки ответа, и вы не будете "тратить" поток на запросы keepalive, которые никогда не придут.

Comet/Websocket работает совершенно по-другому, передавая сообщение специально написанному сервлету (и необязательным фильтрам), и потоки используются только тогда, когда есть сообщения для отправки или данные, которые нужно записать.

ОБНОВЛЕНИЕ 2016-08-19

Tomcat 8.5 и 9.0 полностью сбросили разъем BIO. Это связано с тем, что многие из новых API и технологий (например, Websocket) требуют неблокирующей семантики, а создание неблокирующего сервиса поверх API блокировки очень сложно. Код, необходимый для выполнения этой работы, делал остальную часть кода Tomcat очень уродливым и т.д., И поэтому было принято решение полностью отказаться от BIO-коннектора. Таким образом, для Tomcat 8.5 и далее доступны только NIO, NIO2 и разъемы на основе APR.

Обратите внимание, что с Tomcat 8.5 и 9.0 поддержка Comet была отключена. Использование кометы должно быть заменено на Websocket, который является более стандартным протоколом.

Ответ 2

NIO использует меньшее количество потоков, это означает, что использование порта tcp/ip меньше.

Вы знаете, что порт от 1 до 65534, поэтому мы можем сказать, что NIO может достичь более высокого TPS (транзакции в секунду), чем BIO

Я тестировал оба протокола :HTTP/1.1 и org.apache.coyote.http11.Http11NioProtocol с тем же веб-проектом, с тем же хостом и с тем же server.xml, но с протоколом.

Используйте jmeter для теста.

Я установил 1000 потоков для запуска запроса, когда HTTP/1.1 через несколько минут, порт использования хоста более 30000, а TPS - только 300!

Когда org.apache.coyote.http11.Http11NioProtocol, максимальный счет использования порта никогда не переступает 3000, а tps больше 1200!

Ответ 3

Добавление позднего к этому обсуждению. В этом контексте сопоставлений производительности между блокировкой IO и асинхронным NIO - отличное чтение "Старый способ написания серверов - новый" . В итоге ниже было показано, что нить на модель соединения лучше выполнять и легко писать по сравнению с версия NIO - вопреки распространенному мнению.