Pull to refresh

Comments 16

Я бы добавил к преимуществам возможность аналитики по любым событиям и по времени практически "из коробки". Это очень важная возможность Event sourcing + CQRS архитектуры.

Решений действительно мало, всё сожрала 1С.

Можете привести аналогию Event sourcing + CQRS в 1С, которая "сожрала" другие решения?

Так она сама по себе архитектурно так устроена, что все действия оформляются документами, которые при "проведении" меняют состояние регистров (остатки запасов, состояния и прочее). Сама платформа так устроена. Журнал документов это "event store", регистры это "query storage". Документы легко переносятся из системы управленческого учета, в систему бух. учета и при проведении там, формируют другую базу для запросов. Собственно она и используется и для логистики и для финансов и вообще для любого бизнеса.

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

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

1) Устойчива ли система к дублям входных событий или от клиента требуется гарантия, что он события exactly-once'ит?

2) Есть ли возможность запросить историческое состояние агрегата на фиксированный момент времени? Гарантируется ли в этом случае неизменность агрегата на фиксированный момент времени?

3) Требуется ли от клиента соблюдать упорядоченный поток событий? Если событие с таймстемпом 2 придет раньше события с таймстемпом 1, есть ли гарантии, что агрегат изолирует (не покажет при запросе) изменение 2 до применения изменения 1?

Согласны с замечаниями. Вопросы очень актуальные. Изначально хотели раскрыть эти темы, но всему свое время 😉
Если статья получит хороший отклик, будем дорабатывать фреймворк и раскрывать тему подробнее.

На структурной схеме правая часть, которая описывает Query часть системы, явно нуждается в более подробной детализации:

Event bus -> Events -> Event handling service -> Query Storage
Client -> Query -> Query service -> Query Storage

Спасибо за конструктивное замечание!

Предполагаю, что в коде так всё и сделано. Надо только поправить на рисунке в этой статье.

Интересный подход с кэшом, правильно ли я понял, что в нем висит конечное состояние агрегата с учетом полученных ранее событий? Если да, то означает ли это вычитку всех событий при рестарте приложения или на попадание агрегата в кэш есть триггеры?

Да, поняли правильно. Кэш не персистентный. При рестарте данные кэша теряются, события заново генерируются и кэш собирается с нуля.

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

Для оптимизации можно:

1) Реализовать персистентный кэш

2) Периодически делать снепшоты агрегатов в кэше (хранить в базе с timestamp). При рестарте загрузить агрегат из снепшота и сгенерировать события заново с момента > timestamp

1-вариант несет доп. нагрузку на запись, 2-вариант оптимальнее (учитывая настройку периодичности)

Аxon framework не рассматривали в качестве прототипа? (я не от них)), просто решаем на проекте похожие задачи)

Да, Axon framework рассматривали. Его платный вариант для нашего кейса выходил очень дорого (они считают по кол-ву event-ов). Кроме цены, в целом он неплохой. У Axon framework еще есть open-source вариант, но его я бы не стал рассматривать.

Не стали бы рассматривать по причинам, указанным в статье (комьюнити, время на погружение), или обнаружили более конкрентые недостатки?

Цена была главным виновником отказа.

Sign up to leave a comment.

Articles