Большинство наших проектов работают по простой схеме: пишем скрипт, подключаем несколько дополнительных библиотек, иногда настраиваем работу с внешними файлами — и можно запускать. В рабочих сервисах типа видеостримингов, маркетплейсов или приложений облачной инфраструктуры всё сложнее: там почти всегда есть несколько внутренних приложений, баз данных и связей с другими программами.
У компьютерных проектов есть состояния. Это то, что происходит в системе: что записывается, удаляется и отправляется. Когда архитектура программы сложная, важно вести журнал всех событий: не только понимать текущие состояния, но и знать, как именно они появились. Поэтому в крупных сервисах нужно сохранять историю и последовательность изменений.
Сегодня расскажем про две технологии, Event Sourcing и CQRS, которые помогают управлять программами и их состояниями. В статье разбираем, что это такое, как работает и из каких компонентов состоит.
Архитектурный паттерн
Сначала — главное определение.
Архитектурный паттерн — более абстрактная вещь по сравнению с кодом, библиотекой или фреймворком. Это устойчивый способ организации программы, который уже много раз применяли в других проектах и поняли: такая схема организации удобна и надёжна. Получается, что архитектурный паттерн отвечает на повторяющуюся архитектурную проблему. Например, как хранить данные или как сделать систему устойчивой к сбоям.
Паттерн не указывает строгих правил, как писать конкретный код, а направляет общие действия для создания системы. Это как тип дома: многоэтажка, частный дом или офис. Чётких указаний по материалам и размерам каждого типа нет, но есть общие правила, которым нужно следовать для определённого результата.
Event Sourcing и CQRS — это архитектурные паттерны, которые отвечают за управление операциями и хранение изменений в системе.
CRUD
Event Sourcing и CQRS удобно сравнивать ещё с одной вещью — CRUD. Этой аббревиатурой обозначают четыре основные операции по работе с данными:
- Create (C): создание новой записи. Например, регистрация пользователя или создание комментария.
- Read (R): чтение или получение данных. Это может быть чтение информации из базы данных или просмотр страницы.
- Update (U): обновление. Происходит, если что-то меняется — пароль, текст поста или комментария.
- Delete (D): удаление информации.
Термин появился для работы с базами данных, но может использоваться везде, где есть управление записями.
Полезный блок со скидкой
Если вам интересно разбираться со смартфонами, компьютерами и прочими гаджетами и вы хотите научиться создавать софт под них с нуля или тестировать то, что сделали другие, — держите промокод Практикума на любой платный курс: KOD (можно просто на него нажать). Он даст скидку при покупке и позволит сэкономить на обучении.
Бесплатные курсы в Практикуме тоже есть — по всем специальностям и направлениям, начать можно в любой момент, карту привязывать не нужно, если что.
Что такое Event Sourcing
Event Sourcing отвечает за хранение изменений. Он работает с действиями, которые уже произошли. Это важно.
В простых системах мы храним только текущее состояние, например баланс кошелька. Это одно число, и мы не знаем, как оно получилось. Если его изменить, в будущем система не вспомнит предыдущий баланс. Event Sourcing предлагает делать наоборот: хранить не состояния, а последовательность событий, которые к этому состоянию привели.
Вместо записи текущих фактов у нас есть записи-логи всех законченных операций. Например, без Event Sourcing скрипт кода хранил бы только текущее состояние. При проектировании системы по Event Sourcing приложение помнит все изменения, из которых получается текущий результат, например:
- Сначала был пустой файл.
- Разработчик написал одну часть скрипта.
- Потом ещё часть.
- Пришёл новый разработчик, удалил часть предыдущего кода и добавил свой.
Теперь, если нужно будет открыть файл, программа посмотрит историю изменений и выдаст то, что получилось после них.
Схема работы Event Sourcing
Ниже — общий вариант реализации паттерна. Выглядит сложно, но дальше мы всё разберём.

Если разобрать, что здесь изображено, получается так.
Слева вверху — пользователь и интерфейс UI. Это может быть интерфейс мобильного приложения, сайта в браузере и вообще любого другого сервиса.
Интерфейс передаёт действия пользователя: создать корзину товаров, добавить 1-ю вещь, 2-ю, удалить 1-ю. На это реагируют другие компоненты бизнес-логики, которые создают подходящие события и передают их в следующий компонент системы — Event Store.
Event Store — брокер сообщений, который хранит записи, переданные от предыдущего фрагмента. События не перезаписываются, только добавляются. Порядок добавления тоже важен, потому что от него зависит итоговый результат. Event Store — центр системы.
EventBus транслирует сообщения пользователям. Через промежуточные механизмы все записи о состояниях добавляются в компонент Read Database.
Read Database или Read Model — база данных событий, которую можно использовать. Эта часть должна быстро отвечать на запросы пользователя. Посмотрите на схему: Read Database транслирует текущее состояние в интерфейс.
Рядом с Eventbus есть надпись Eventual Consistency. Это значит, что между созданием записи и добавлением в базу есть задержка, но в итоге всё в системе становится согласованным. Если пользователь что-то сделал в системе, это обязательно попадает в базу данных.
Replay Events — одна из главных частей Event Sourcing. Если что-то изменилось в программе или обнаружилась сложная ошибка, можно проиграть события заново или очистить Read Database. Это возможно потому, что все записи-события неизменяемы.
Преимущества и недостатки Event Sourcing
Главное преимущество — полная история изменений. Это упрощает проверки системы, отладку и восстановление данных после ошибок. Ещё становится проще пересчитать все данные по новым правилам. Паттерн хорошо подходит для приложений со сложной бизнес-логикой, например в финансовой или юридической системе.
Минус в том, что реализация подхода может быть сложной в понимании и реализации. Простая задача из обычной системы становится цепочкой событий и дополнительных абстрактных сущностей в Event Sourcing. А если событий слишком много, есть опасность проблем с производительностью и восстановлением состояния.
Бонус для читателей
Если вам интересно погрузиться в мир ИТ и при этом немного сэкономить, держите наш промокод на курсы Практикума. Он даст вам скидку при оплате, поможет с льготной ипотекой и даст безлимит на маркетплейсах. Ладно, окей, это просто скидка, без остального, но хорошая.
Что такое CQRS
CQRS — архитектурный паттерн для разделения операций чтения и записи. Название расшифровывается как Command Query Responsibility Segregation: «Разделение ответственности при выполнении команд и запросов».
CQRS нужен там, где чтение и запись данных начинают друг другу мешать. Например, добавление товаров в корзину перегружает приложение, и в итоге пользователи не могут просмотреть каталог товаров, потому что он перегружен работой с созданием записей. Поэтому паттерн предлагает разделить модель записи и модель чтения. Для записи и чтения используются разные части программы. Иногда — разные базы данных.
Про Event Sourcing и CQRS часто рассказывают вместе, но использовать их одновременно необязательно. При этом один паттерн хорошо дополняет другой, что особенно хорошо в системах с высокой нагрузкой, сложной бизнес-логикой и требованиями к аудиту.
Схема работы CQRS
Вот примерная схема работы паттерна CQRS:

Теперь разберём, как это работает.
Клиент-пользователь работает с интерфейсом UI. Это то же самое, что происходит в начале по схеме Event Sourcing.
UI запускает создание одного из двух событий: команды или запроса. Это ключевая идея паттерна, потому что два вида событий никогда не смешиваются.
Команда (Command) создаёт запись в базе данных. Этот этап обозначен на схеме как Write Database.
Read Database — часть системы, которая отвечает за то, чтобы запись можно было прочесть. Обратите внимание, что на этой схеме тоже есть пометка Eventual Consistency — состояние системы всегда в итоге становится согласованным и стабильным.
Запрос (Query) читает нужную запись в базе данных.
Преимущества и недостатки CQRS
Основной плюс паттерна в масштабируемости. Чтение и запись изменяют и оптимизируют независимо друг от друга. В итоге CQRS сильно упрощает оптимизацию запросов. Модель чтения можно сделать простой и быстрой, без учёта сложных бизнес-правил для создания записей. Это полезно для дашбордов, аналитики и мониторинга.
Минус в том, что CQRS увеличивает количество компонентов в системе. Появляются разные модели, потоки данных и синхронизация между ними. Это усложняет работу. Для простых приложений паттерн CQRS не нужен, его лучше использовать в сервисах с высокой нагрузкой и сложностью.
Событийно-ориентированная архитектура (EDA)
Event-driven architecture, EDA, или событийно-ориентированная архитектура, основана на идее, что компоненты системы не вызывают друг друга напрямую, а реагируют на события.
Пример — сервис по принятию заказов для компании готовки и доставки еды. Сначала пользователь использует интерфейс и создаёт заказ. Интерфейс создаёт событие OrderCreated, которое встаёт в очередь. На этом первая часть работы заканчивается, и остальные части приложения начинают реагировать, потому что отслеживают появление событий типа OrderCreated:
- Склад создаёт заказ.
- Сервис оплаты создаёт счёт на оплату.
- Модуль уведомлений присылает уведомление на почту клиента.
Ни одна часть не вызывает другую прямо, и это позволяет изолировать составные компоненты всей программы для надёжности и стабильности.
Архитектура типа EDA выступает основным каркасом, а поверх неё можно положить паттерны Event Sourcing и CQRS.
Компоненты событийно-ориентированной архитектуры
Так может выглядеть архитектурная схема. Сначала посмотрите, а потом подробно разберём, как она работает:

Что здесь есть:
- Системы A, B, C, D.
- События, которые создаёт система A.
- Центральный брокер сообщений. На предыдущих схемах он назывался Event Store. Брокер публикует события, чтобы они были видны всем внутренним системам.
И при этом системы не знают друг о друге напрямую.
Действие-триггер происходит и создаётся в системе A. Например, сработал сигнал, что количество посетителей сайта резко увеличивается и мощности сервера не справляются. Создающий события компонент называется Producer.
Система A посылает созданное событие в Event Broker. Он принимает событие и доставляет другим системам, которые настроены так, чтобы им присылали события определённых типов. Теперь остальные системы знают, что случилось. Например, «количество пользователей превысило отметку в 100 000 человек». В зависимости от типа систем они могут подключить новые мощности, проверить скорость работы, запустить тестирование после перенастройки сервисов.
Между системой A и Event Broker есть промежуточный слой, который называется Adapter. Он обрабатывает событие, чтобы его можно было передать в брокер сообщений.
DS, или Data Store, — внутреннее хранилище брокера, чтобы события не потерялись.
Topic Space означает, что события делятся по группам и отправляются в разные системы.
Когда появляется Event Sourcing: если при использовании проходящие через брокер события дополнительно сохраняются в неизменяемом хранилище событий. Это дополнительное хранилище становится источником истины системы, то есть хранит неизменяемую последовательность событий, по которой можно восстановить конечный результат — или откатить систему до нужной версии.
Остальные системы — B,C и D — выступают как потребители событий. Такие компоненты называются Consumer. Каждый Consumer подписан на свой тип событий и не может напрямую взаимодействовать с другими системами.
Где проявляется CQRS: разные потребители событий формируют собственные модели чтения, оптимизированные под конкретные сценарии. Поэтому CQRS на этой схеме уже присутствует и работает.
Проектирование системы
Проектированием занимаются системные архитекторы, но большинство разработчиков начиная с уровня мидл тоже должны уметь это делать хотя бы частично. От понимания принципов архитектуры зависит рост программиста как самостоятельного специалиста и в перспективе руководителя и наставника начинающих коллег.
В системной архитектуре нужно учитывать много вещей, которые могут повлиять на работу с будущей программой. Например, события создаются на основе уже совершённых действий, а система умеет работать с разными форматами событий. Со временем формат данных может поменяться, но старые события всё равно должны быть доступны.
В реальных условиях ошибки проектирования становятся видны довольно быстро: появляется сложная логика и временные решения-костыли, которые в итоге создают технический долг и мешают развитию сервиса.
Использование Spring Boot и Axon Framework
Вот две технологии, которые ускоряют разработку таких систем.
Spring Boot — инструмент для быстрой сборки серверного java-приложения. Он отвечает за то, чтобы в сервисе были:
- сервер;
- необходимые зависимые технологии;
- правильная конфигурация;
- связи между разными компонентами — интеграции.
Axon Framework упрощает создание систем с Event Sourcing и CQRS. Он помогает:
- принять команду (Command);
- сгенерировать событие (Event) и сохранить его в Event Store;
- разослать событие подписчикам и обновить Read Database (Read Model), которая видна пользователям.
Мониторинг и анализ событий
Мониторинг означает детальное наблюдение и возможность получения информации обо всём, что происходит в программе.
В событийных системах отслеживание происходящего критически важно. Из-за сложной архитектуры события проходят через несколько компонентов, и ошибка может произойти на любом этапе. Без наблюдения такие проблемы сложно исправлять.
Мониторинг поможет понять, где система тормозит. Например, если события долго обрабатываются в системах Consumer. Это сразу видно по метрикам и логам.
Ещё мониторинг важен для анализа бизнес-процессов. По истории событий можно восстановить путь пользователя и найти узкие места в приложениях. Это полезно не только разработчикам, но и продуктовым командам.
Главное, что нужно запомнить: без мониторинга событийная архитектура быстро превращается в хаос. Поэтому её нужно закладывать в систему с самого начала.
Ищете работу в IT?
Карьерный навигатор Практикума разберёт ваше резюме, проложит маршрут к первому работодателю, подготовит к собеседованиям в 2026 году, а с января начнёт подбирать вакансии именно под вас.
Где всё это используется
Event Sourcing и CQRS применяют во многих реальных продуктах. Особенно там, где важны надёжность и прозрачность.
Классический пример приложений с Event Sourcing — банковские системы. Каждая операция в таком сервисе равна событию, которое нельзя изменить или удалить. Это критически важно для аудита и расследований ошибок.
В играх Event Sourcing используют для хранения действий игроков, а в e-commerce события фиксируют путь заказа от создания до доставки. Тогда при поломке всегда можно понять, где произошёл сбой.
CQRS хорошо подходит аналитическим системам со сложными отчётами. Пользователи работают и пользуются основными функциями, пока отчёты считаются в фоне.
Ещё CQRS полезен в системах с микросервисами, где каждый сервис может иметь свою модель чтения и запросов, оптимизированную под конкретные задачи.
При всей пользе эти паттерны не универсальны и подходят не для всех проектов. Например, в простых приложениях часто достаточно простого устройства. А если появилась необходимость масштабирования и возможность роста, всегда можно использовать инструменты и фреймворки для скорости и быстро переделать приложение по правилам событийно-ориентированной архитектуры.
