Reactor
Что такое модель реактора
вики:“The reactor design pattern is an event handling pattern for handling service requests delivered concurrently by one or more inputs. The service handler then demultiplexes the incoming requests and dispatches them synchronously to associated request handlers.”
Почему Реактор?
Для приложений скорость обработки ЦП намного выше, чем скорость ввода-вывода. Если ЦП блокирует операции ввода-вывода (такие как чтение фрагмента данных из сокета), это, очевидно, нерентабельно. Лучший способ - разделить его на несколько процессов или потоков для обработки, но это принесет некоторые накладные расходы на переключение процессов.Представьте, что процесс читает одни данные за 500 мс, в течение которых процесс переключается на них 3 раза, но ЦП не может этого сделать. что угодно. , просто отключитесь вот так, разве оно того не стоит?
В это время первопроходцы нашли управляемый событиями или обратный вызов способ добиться этого. Таким образом, прикладной бизнес регистрирует обработчик событий у посредника, когда ввод-вывод готов, на посреднике генерируется событие, и обработчик уведомляется об обработке. Этот метод обратного вызова также отражает «голливудский принцип» — «Не звоните нам, мы позвоним вам», который также полезен в знакомом IoC. Кажется, что разработка программного обеспечения действительно интероперабельна!
Сценарии применения Reactor
Ядром Reactor является решение проблемы множественных запросов. Вообще говоря, параллелизм сценариев приложения Thread-Per-Connection не особенно велик. Если параллелизм слишком велик, ресурсы потока будут исчерпаны мгновенно, что приведет к блокировке службы. В настоящее время для решения проблемы необходим режим Reactor. Эта проблема. Reactor значительно сокращает использование ресурсов потоков благодаря идее мультиплексирования.
Структура реактора
На картинке выше показана модель Reactor, основные задействованные классы:
-
Initiation Dispatcher
: Контейнер EventHandler, используемый для регистрации, удаления EventHandler и т. д.; кроме того, он вызывает метод select синхронного демультиплексора событий в качестве точки входа в режим Reactor, чтобы заблокировать возврат ожидания события, а когда событие блокировки возвращает, распределите дескриптор события по соответствующим дескрипторам The EvenHandler. -
Even Handler
: определяет метод обработки событий. -
Handle
: дескриптор в операционной системе — это абстракция ресурсов на уровне операционной системы, которая может быть открытым файлом, соединением (сокетом), таймером и так далее. -
Synchronous Event Demultiplexer
: Используйте цикл обработки событий, чтобы заблокировать все ресурсы. Когда синхронная операция может быть инициирована с ресурсом без блокировки, демультиплексор отправляет ресурс диспетчеру.
Диаграмма последовательности реакторов
- Инициализируйте InitationDispatcher и инициализируйте Map of Handle для EventHandler.
- Зарегистрируйте EvenHandler в InitationDispatcher, каждый EventHandler содержит ссылку на соответствующий Handle, тем самым устанавливая сопоставление Handle и EventHandler (Map).
- Вызовите метод handle_events() класса InitiationDispatcher, чтобы запустить цикл обработки событий. В цикле событий вызовите метод select() (синхронный демультиплексор событий), чтобы заблокировать и дождаться возникновения события.
- Когда происходит событие одного или нескольких дескрипторов, метод select() возвращает значение, и InitiationDispatcher находит зарегистрированный EventHandler в соответствии с возвращенным дескриптором и вызывает метод handle_events() EventHandler.
- В методе handle_events() EventHandler вы также можете зарегистрировать новый обработчик событий с помощью InitiationDispatcher. Например, для AcceptorEventHandler, когда есть новое клиентское соединение, он сгенерирует новый обработчик событий для обработки нового соединения и зарегистрирует его с помощью ИнициацияДиспетчер.
Схема реактора
Режим однопоточного реактора
Проще говоря, получение и обработка запросов обрабатываются в одном потоке.
Для некоторых сценариев приложений с небольшой емкостью можно использовать однопоточную модель. Однако он не подходит для сценариев приложений с высокой нагрузкой, большим параллелизмом или большим объемом данных по следующим основным причинам: ① Поток NIO обрабатывает сотни или тысячи ссылок одновременно, что не может поддерживаться с точки зрения производительности.Даже если загрузка ЦП потока NIO достигает 100%, он не может справиться с чтением и отправкой массивных сообщений; ② Когда поток NIO перегружен, скорость обработки будет замедляться, что приведет к большому количеству тайм-аутов клиентских соединений, которые часто будут повторно передаваться после тайм-аута, что увеличит нагрузку на поток NIO, что в конечном итоге приведет к большому количеству бэклогов сообщений и таймаутов обработки, что становится узким местом в производительности системы;
Режим многопоточного реактора
Проще говоря, получение запросов и обработка запросов обрабатываются в разных потоках.
Обычно существует только один mainReactor, который в основном отвечает за получение соединения от клиента и передачу его в subReactor. Обычно есть несколько подреакторов, которые в основном отвечают за связь с клиентами.
Примечание. На изображении выше используетсяThread Pool
Чтобы справиться с трудоемкой бизнес-логикой, улучшите реакцию ввода-вывода потока Reactor, чтобы не задерживать обработку последующих запросов ввода-вывода из-за некоторой трудоемкой бизнес-логики.
Плюсы и минусы Реактора
преимущество:
- Общие для большинства шаблонов проектирования: разделение, улучшение возможности повторного использования, модульность, переносимость, управление событиями, детальное управление параллелизмом и т. д.
- Что более существенно, так это улучшение производительности, то есть нет необходимости соответствовать потоку для каждого Клиента, что сокращает использование потоков.
недостаток:
- По сравнению с традиционной простой моделью Reactor добавляет определенную степень сложности, поэтому она имеет определенный порог и ее нелегко отлаживать.
- Для режима Reactor требуется поддержка базового демультиплексора синхронных событий, например, поддержка Selector в Java и поддержка системных вызовов select в операционной системе.Если вы хотите реализовать демультиплексор синхронных событий самостоятельно, это может быть не так эффективно.
- Режим Reactor по-прежнему реализуется в том же потоке, когда IO читает и записывает данные.Даже если используется несколько механизмов Reactor, если в каналах, которые совместно используют Reactor, выполняется чтение и запись долгосрочных данных, это повлияет на другие каналы в этом Reactor. , Например, при передаче больших файлов операция ввода-вывода повлияет на соответствующее время других клиентов, поэтому для такого рода операций может быть лучшим выбором использовать традиционное Thread-Per-Connection или использовать Proactor в это время. , модель.
Реализация кода реактора
уведомление
Представьте NIO и Netty, связанные с Reactor.