Interested Article - Реактор (шаблон проектирования)

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

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

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


Обзор

Первоначальной мотивацией для шаблона реактора были практические соображения по модели клиент-сервер в больших сетях, такие как проблема C10k для веб-серверов .

Наивный подход к обработке запросов на обслуживание от многих потенциальных конечных точек, таких как сетевые сокеты или файловые дескрипторы , заключается в прослушивании новых запросов из цикла событий, и немедленном чтении самого раннего запроса. Как только весь запрос будет прочитан, его можно обработать и переслать, напрямую вызвав соответствующий обработчик. Подобный полностью «итеративный» сервер, обрабатывающий один запрос от начала до конца за цикл событий, логически правилен. Однако он отстанет, если получит несколько запросов подряд. Итеративный подход не может масштабироваться, поскольку чтение запроса блокирует единственный поток сервера до тех пор, пока не будет получен полный запрос. А операции ввода-вывода обычно выполняются намного медленнее, чем другие вычисления.

Одной из стратегий преодоления этого ограничения является многопоточность: за счет немедленного отделения каждого нового запроса в отдельный рабочий поток, первый запрос больше не будет блокировать цикл событий, который может немедленно завершить итерацию и обработать другой запрос. Такая конструкция «поток на соединение» масштабируется лучше, чем чисто итеративная, но она содержит свои ограничения. С точки зрения базовых системных ресурсов каждый новый поток или процесс требует дополнительных затрат памяти и времени обработки (из-за переключения контекста ). Фундаментальная неэффективность каждого потока, ожидающего завершения ввода-вывода, также не решена.

С точки зрения проектирования, оба подхода тесно связывают общий демультиплексор с конкретными обработчиками запросов, что делает серверный код хрупким и утомительным для модификации. Эти соображения подсказывают несколько основных проектных подходов:

  1. Оставить однопоточный обработчик событий; многопоточность приводит к накладным расходам и сложности, не решая реальную проблему блокировки ввода-вывода.
  2. Использовать механизм уведомления о событиях для демультиплексирования запросов только после завершения ввода-вывода (чтобы ввод-вывод фактически не блокировался).
  3. Зарегистрировать обработчики запросов как обратные вызовы с обработчиком событий для лучшего разделения задач.

Объединение этих идей ведет шаблону реактора, который сочетает в себе преимущества однопоточной обработки с высокой пропускной способностью и масштабируемостью.

Применение

Шаблон реактора может стать хорошей отправной точкой для решения любой параллельной проблемы обработки событий. Этот шаблон также не ограничивается сетевыми сокетами; аппаратный ввод-вывод, доступ к файловой системе или базе данных , меж-процессное взаимодействие и даже абстрактные системы передачи сообщений — все это возможные варианты использования. </link> [ нужна цитата ]

Однако у шаблона реактора есть ограничения, главным из которых является использование обратных вызовов, которые усложняют анализ и отладку программы — проблема, характерная для проектов с инвертированным управлением . Более простые подходы: «поток на соединение» и полностью итеративный подход, позволяют избежать этого и могут быть приемлемыми решениями, если не требуется масштабируемость или высокая пропускная способность. </link>

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

Приложения

Шаблон реактора (или его вариант) нашел место во многих веб-серверах, серверах приложений и сетевых платформах:

Состав

Structure

Реактивное приложение состоит из нескольких активных частей и опирается на некоторые механизмы поддержки:

Handle
Идентификатор и интерфейс к экземпляра запроса с IO и данными. Обычно представлен в форме сокета, файлового дескриптора, или похожего механизма предоставляемого большинством современных ОС.
Demultiplexer
Извещатель событий, который может эффективно наблюдать "статус" хендлов, и извещать суб-системы о изменениях "статуса" (типичное - что хендл-IO стал "готов к чтению"). Исторически эта роль заполнялась , или более современные примеры включают epoll , , and .
Dispatcher
Цикл обработки событий реактивного приложения. Этот компонент управляет регистраций обработчиков событий, которые вызываются на появление соответствующего события.
Event Handler
Обработчик запросов, реализует логику обработки специфическую для каждого типа запросов. Паттерн реактора полагается на динамическую регистрацию его диспетчере в виде обратных вызовов, для большей гибкости. По умолчанию, реактор не использует мульти-поточность, но вызывает обработчик запроса в нитке диспетчера.
Event Handler Interface
Абстрактный класс-интерфейс, предоставляет основные свойства и методы обработчика события. Конкретный обработчик реализует интерфейс, а диспетчер посредством его оперирует обработчиком события.

Варианты

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

Одна из основных модификаций — вызывать обработчики событий в их собственных потоках для большей параллелизма. Запуск обработчиков в пуле потоков вместо запуска новых потоков по мере необходимости еще больше упростит многопоточность и минимизирует накладные расходы. Т. о. пул потоков - естественное дополнение шаблона реактора во многих случаях использования.

Другой способ максимизировать пропускную способность — частично воспроизвести подход сервера «поток на соединение» с размножаемыми параллельными диспетчерами/циклами событий. Однако вместо количества соединений можно настроить количество диспетчеров, чтобы оно соответствовало доступным ядрам ЦП базового оборудования.

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

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

Смотрите также

Связанные шаблоны:

Примечания

  1. Практическое правило софто-строения говорит что если требования к приложению потенциально могут увеличить существующие и предполагаемые лимиты, можно ожидать что однажды так и будет.

Ссылки

  1. // Pattern Languages of Program Design / Coplien. — 1st. — Addison-Wesley, 1995. — Vol. 1. — ISBN 9780201607345 .
  2. Devresse. . 2nd Thematic CERN School of Computing . CERN (20 июня 2014). Дата обращения: 14 сентября 2023. 8 августа 2022 года.
  3. Escoffier, Clement. // Reactive Systems in Java / Clement Escoffier, Ken Finnegan. — O'Reilly Media, November 2021. — ISBN 9781492091721 .
  4. Garrett. . NGINX . F5, Inc. (10 июня 2015). Дата обращения: 10 сентября 2023. 20 августа 2023 года.
  5. Kegel. . Dan Kegel's Web Hostel (5 февраля 2014). Дата обращения: 10 сентября 2023. 6 сентября 2023 года.
  6. . POCO Project 21–22. Applied Informatics Software Engineering GmbH (2010). Дата обращения: 20 сентября 2023.
  7. Stoyanchev. . Spring.io (9 февраля 2016). Дата обращения: 20 сентября 2023.

Внешние ссылки

Конкретные приложения:

  • Alexeev, Andrew. // The Architecture of Open Source Applications / Brown ; Wilson. — Lulu.com, 30 March 2012. — Vol. 2. — ISBN 9781105571817 .

Примеры реализации:

[[Категория:Шаблоны проектирования]] [[Категория:Параллельные вычисления]] [[Категория:Страницы с непроверенными переводами]] [[Category:Concurrent computing]] [[Category:Software design patterns]]

Источник —

Same as Реактор (шаблон проектирования)