УДК 61 Медицина. Охрана здоровья
УДК 62 Инженерное дело. Техника в целом. Транспорт
ГРНТИ 50.41 Программное обеспечение вычислительных машин, комплексов и сетей
ОКСО 02.07.01 Компьютерные и информационные науки
ББК 3297 Вычислительная техника
ТБК 51 Информатика. Вычислительная техника
BISAC COM051230 Software Development & Engineering / General
Рассмотрены преимущества применения архитектурного подхода Command-query responsibility segregation (разделение ответственности за команду-запрос) в высоконагруженных приложениях. Выявлены преимущества и недостатки использования данной технологии.
высоко нагруженные приложения, обработка, низкие задержки, архитектура
Актуальность использования специализированных архитектурных подходов при проектировании высоконагруженных приложений
Приложения решают разные задачи повсеместно. Но есть спектр задач в различных предметных областях, где отказоустойчивость, надежность и время отклика на запрос клиента имеют большую значимость. Классические архитектурные подходы (model-view-controller, model-view-viewmodel и другие многослойные подходы) являются экономически выгодными в начале жизненного цикла программного обеспечения, однако дальнейшее их развитие и поддержание работоспособности, особенно при высоких нагрузках, является большой статьей расходов. Этому можно найти подтверждение если рассмотреть методы решения проблем, связанных с чрезмерной нагрузкой: внедрение конкурентной обработки запросов, создание нескольких копий приложения, реплик хранилища данных.
В свою очередь, существуют архитектурные подходы изначально ориентированные на необходимость масштабирования и проведения оптимизаций в рамках жизненного цикла продукта. Одним из таких подходов является Command Query Responsibility Segregation (разделение ответственности за запросы и команды).
Описание отличительных особенностей CQRS-подхода
CQRS – это архитектурный подход в котором операции чтения отделены от операций записи. Он был сформулирован Грегом Янгом на основе принципа Command-query separation (разделение команды и запроса). Основная причина развития и актуализации данного подхода это неравномерная нагрузка на подсистемы записи и чтения в приложениях, что создает проблемы с производительностью в классических архитектурных подходах. Классическая многослойная архитектура показана на рисунке 1.
Многослойная архитектура – самый популярный способ организации приложений. Согласно её простой вариации, приложение делится на три части: слой пользовательского интерфейса, слой бизнес-логики, слой данных.
Рис. 1 Многослойная архитектура приложений.
Слой данных как правило представляется в виде некого абстрактного репозитория (Repository) абстрагирующего разработчика от конкретного хранилища данных.
Слой бизнес логики содержит объекты инкапсулирующие «бизнес-правила» приложения.
Слой пользовательского интерфейса обрабатывает запросы, приходящие от пользователя, передает их в слой бизнес логики, и затем через репозиторий происходит взаимодействие с хранилищем данных.
Отсюда становится очевидным, что все запросы на чтение и изменение данных фокусируются в бизнес-логике. Схема обработки запроса показана на рисунке 2.
Рис. 2 Схема обработки запроса приложением с многослойной архитектура.
Как следствие при росте количества пользовательских запросов слой бизнес-логики становится «бутылочным-горлышком», и приложение теряет возможность отзывчиво реагировать на пользовательскую активность, что проявляется различными time-out ошибками, вплоть до невозможности дальнейшего функционирования. В большинстве случаев для решения данных проблем разработчики могут внедрить в приложение конкурентную обработку запросов или использовать несколько его копий и репликацию базы данных.
Однако, данных проблем можно избежать, если изначально придерживаться CQRS подхода. Система построенная на его основе, не будет смешивать запросы на чтение (Query) и команды на запись (Command) (рисунок 3). Разделение предлагаемое CQRS подходом, может быть достигнуто группировкой логики обработки запросов в одном слове, а команд в другом. Так же необходимо отметить, что вышеописанные слои могут использовать разные хранилища данных и оптимизироваться по отдельности. К часто применяемой на практике особенностью данного подхода относится «конвейер обработки» запроса (pipeline). Для внедрения конвейера, программисту необходимо реализовать его звенья и зарегистрировать для каждого входящего запроса.
Рис. 3 Схема обработки запроса в приложении с CQRS-подходом.
Пример абстрактного «конвейера обработки» показан на рисунке 4.
Рис. 4 Обобщенный «конвейер обработки» CQRS-вызова.
Конвейер на рисунке 4 состоит из четырех элементов:
1. ValidationPipe.cs содержит логику проверки входящих вызовов (например: существование записи в базе данных, возможность выполнить операцию), и случает отрицательного результата генерирует исключение.
2. LogPipe.cs выполняет логирование входящих данных, благодаря чему упрощается процесс отладки работающего сервиса.
3. Handler.cs основной обработчик вызова, в зависимости от вызова выполняет определенную логику
4. AfterAction.cs выполняется после успешного выполнения вызова, что позволяет, например, обеспечить логирование результата, отправку уведомлений о завершении на почту и т. п.
Достоинства и недостатки CQRS-подхода
Достоинства:
1. Легче расширять функциональность
2. Меньше зависимостей в каждом классе
3. Выше отзывчивость приложения, за счет разделения операций чтения и потенциально долгих операций записи
4. Возможность использовать различные хранилища данных для потоков чтения и и записи
Недостатки:
1. Больше программного кода
2. Много мелких классов
3. Невозможность целиком придерживаться принципов CQRS
4. Не имеет смысла для приложений с маленькой пиковой нагрузкой
5. Плохо сочетается с CRUD
Заключение. Обеспечение высокой масштабируемости приложений – это экономически значимая задача, и CQRS подход в построении архитектуры приложения может значительно упростить и удешевить процессы модификации и расширения программного обеспечения. Данный подход позволяет проводить оптимизацию конвейеров запросов и команд любым способом. При этом изменения в одном конвейере не нарушат работу другого. Однако, несомненно, жесткое соблюдение данного подхода может привести к чрезмерному переусложнению архитектуры приложения и значительно повысить стоимость его сопровождения.
1. Ричардсон Крис. Микросервисы. Паттерны разработки и рефакторинга. СПб.: Питер, 2019. 544 с.
2. Басс Л., Клементс П., Кацман Р. Архитектура программного обеспечения на практике. СПб.: Питер, 2006. 575 с.