UDK 61 Медицина. Охрана здоровья
UDK 62 Инженерное дело. Техника в целом. Транспорт
GRNTI 50.41 Программное обеспечение вычислительных машин, комплексов и сетей
OKSO 02.07.01 Компьютерные и информационные науки
BBK 3297 Вычислительная техника
TBK 51 Информатика. Вычислительная техника
BISAC COM051230 Software Development & Engineering / General
The advantages of using the architectural approach Command-query responsibility segregation in high-load applications are considered. The advantages and disadvantages of using this technology are revealed.
high loaded applications, processing, low latency, architecture.
Актуальность использования специализированных архитектурных подходов при проектировании высоконагруженных приложений
Приложения решают разные задачи повсеместно. Но есть спектр задач в различных предметных областях, где отказоустойчивость, надежность и время отклика на запрос клиента имеют большую значимость. Классические архитектурные подходы (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. Richardson Kris. Mikroservisy. Patterny razrabotki i refaktoringa. SPb.: Piter, 2019. 544 s.
2. Bass L., Klements P., Kacman R. Arhitektura programmnogo obespecheniya na praktike. SPb.: Piter, 2006. 575 s.