Модель резьбы Netty для статей серии Netty

задняя часть Netty

предисловие

Когда мы используем Netty для разработки на стороне сервера, мы обычно определяем два пула потоков NioEventLoopGroup, пул потоков «bossGroup» для обработки клиентских подключений и пул потоков «workGroup» для обработки операций чтения и записи. Итак, почему мы это делаем? Какая польза от этого? Можем ли мы просто использовать одну NioEventLoopGroup? Вот о чем мы сегодня поговорим — о потоковой модели Netty.

Модель резьбы Reactor

По сути, модель потоков Netty является реализацией шаблона Reactor, а что такое шаблон Reactor?

Режим Reactor основан на разработке, управляемой событиями. Основные компоненты включают Reactor и пул потоков. Reactor отвечает за мониторинг и распределение событий, а пул потоков отвечает за обработку событий. В зависимости от количества Reactors и количества пулов потоков, Реакторы делятся на три типа Модель:

  • Модель с одним потоком (один поток Reactor с одним потоком)
  • Многопоточная модель (многопоточность с одним Reactor)
  • Модель многопоточности ведущий-ведомый (многопоточность с несколькими реакторами)

однопоточная модель

Reactor_1

Изображение взято из:гы. В это время. Освего. Квота/Вход/Введение продукта…

  • Внутренний проход реактораselectorОтслеживайте события подключения и передайте событие после получения событияdispatchРаспространение, если это событие установления соединения, оно будет обработано Акцептором,AcceptorПримите соединение через accept и создайте обработчик для обработки различных событий, следующих за соединением.Если это событие чтения-записи, напрямую вызовите соответствующее соединение.Handlerиметь дело с
  • Обработчик завершает бизнес-процесс чтение->(декодирование->вычисление->кодирование)->отправка
  • Преимущества этой модели просты, но недостатки очевидны: когда обработчик заблокирован, обработчики и акцепторы других клиентов не будут выполняться, и высокая производительность не может быть достигнута, она подходит только для очень быстрых сценариев обработки бизнеса.

многопоточная модель

Reactor_2

Изображение взято из:гы. В это время. Освего. Квота/Вход/Введение продукта…

  • В основной нити объект реактора контролирует событие соединения через селектор. После получения события распределите событие, если это подключение для установления события, примите обработку акцептора и создайте обработчик для обработки последующего Мероприятие, в то время как обработчик отвечает только за ответ, не выполняет бизнес-операцию, то есть только чтение данных чтения и записи данных записи, обработка бизнеса передается в пул резьбы для обработки
  • Пул потоков выделяет поток для завершения реальной бизнес-обработки, а затем передает результат ответа обработчику основного процесса для обработки, и обработчик отправляет результат клиенту (ниже приведен основной код).

Reactor_Handler_Pool

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

Многопоточная модель ведущий-ведомый (наиболее популярная)

Reactor_3

Изображение взято из:гы. В это время. Освего. Квота/Вход/Введение продукта…

  • Есть несколько реакторов,Каждый Reactor имеет свой собственный селектор селектора., потоки и отправка
  • mainReactor в основном потоке отслеживает событие установления соединения через собственный селектор, получает событие через Accpetor и назначает новое соединение дочернему потоку.
  • SubReactor в подпотоке добавляет соединение, выделенное mainReactor, в очередь соединений для прослушивания через собственный селектор и создает обработчик для обработки последующих событий.
  • Обработчик завершает полный бизнес-процесс чтение->обработка бизнеса->отправка

Reacotr_Mutiple

Связь между потоковой моделью в Netty и Reactor

Netty в основном опирается на пул NioeventLoopGroup для реализации конкретной модели резьбы.

однопоточная модель

Однопоточная модель заключается в том, чтобы указать только один поток для выполнения клиентского подключения и операций чтения и записи, то есть для выполнения в одном Reactor.Соответствующая реализация в Netty заключается в том, чтобы установить количество потоков NioEventLoopGroup равным 1. Основной код :

 NioEventLoopGroup group = new NioEventLoopGroup(1);
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(group)
                .channel(NioServerSocketChannel.class)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .option(ChannelOption.SO_BACKLOG, 1024)
                .childHandler(new ServerHandlerInitializer());

Его рабочий процесс примерно таков:

Reactor_Netty_1

Приведенная выше однопоточная модель соответствует однопоточной модели Reactor.

многопоточная модель

Многопоточная модель заключается в выполнении обработки клиентских подключений в одном Reactor, а затем передаче бизнес-обработки в пул потоков.Основной код выглядит следующим образом:

NioEventLoopGroup eventGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(eventGroup)
        .channel(NioServerSocketChannel.class)
        .option(ChannelOption.TCP_NODELAY, true)
        .option(ChannelOption.SO_BACKLOG, 1024)
        .childHandler(new ServerHandlerInitializer());

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

@Override
public ServerBootstrap group(EventLoopGroup group) {
    return group(group, group);
}

Рабочий процесс выглядит следующим образом:

Reactor_Netty_2

Многопоточная модель ведущий-ведомый (наиболее часто используемая)

Многопоточная модель master-slave имеет несколько Reactors, то есть несколько селекторов, поэтому мы определяем bossGroup и workGroup.Основной код выглядит следующим образом:

NioEventLoopGroup bossGroup = new NioEventLoopGroup();
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup,workerGroup)
        .channel(NioServerSocketChannel.class)
        .option(ChannelOption.TCP_NODELAY, true)
        .option(ChannelOption.SO_BACKLOG, 1024)
        .childHandler(new ServerHandlerInitializer());

Рабочий процесс выглядит следующим образом:

Netty_reactor_1

Примечание: на самом деле в Netty пул потоков bossGroup будет случайным образом выбирать только один поток для обработки клиентских подключений.В то же время NioServerSocketChannel привязан к потоку bossGroup, а NioSocketChannel привязан к потоку workGroup.

резюме

Вышеприведенное суммирует три модели Reactor и соответствующую реализацию в Netty, в Netty, в большинстве наших или в многопоточной модели master-slave. Что касается обучения Реактора, наиболее авторитетной информацией должен быть Дуг Ли Великий Бог.Scalable IO in Java, Заинтересованные студенты могут посмотреть

использованная литература