Лог как источник истины: почему событийная модель начинает побеждать точечные интеграции
Как переход от двусторонних вызовов к единому журналу событий упрощает связность систем и убирает хрупкость двойных записей.
Когда в компании несколько систем - CRM, склад, бухгалтерия, интернет-магазин - рано или поздно появляется вопрос: как им обмениваться данными? Первый ответ почти всегда одинаковый: давайте система A при изменении будет вызывать систему B. Это кажется простым, пока систем две или три.
Когда их становится шесть или семь, паутина двусторонних вызовов превращается в источник постоянной боли - и отправная точка для решения этой проблемы состоит в том, чтобы думать об интеграциях как о дисциплине, а не как о побочном эффекте. Одна система недоступна - другая не знает, что делать с ошибкой. Данные записались в одном месте, но не записались в другом. Восстановить последовательность событий после сбоя невозможно, потому что каждая система хранит только своё.
Что такое событийная модель
Идея, которая набирает популярность в инженерных кругах, - это хранить не состояние, а историю изменений. Вместо того чтобы каждая система при каждом изменении звонила всем заинтересованным, она пишет событие в общий журнал. Остальные системы читают журнал и реагируют на то, что им важно.
Событие - это факт: "заказ создан", "оплата получена", "остаток на складе изменился". Оно неизменяемо. Оно случилось - и это записано. Текущее состояние любого объекта - это результат применения всех событий, которые с ним происходили. Допустимо ли небольшое отставание в получении этих событий - вопрос контекста; стоит задать его до принятия архитектурного решения: когда бизнесу нужен поток, а когда хватает каждые 15 минут.
Такой подход называют event sourcing, и он не нов. Но именно сейчас появляется достаточно инструментов, чтобы его можно было применять без боли на уровне продуктовых команд, а не только в финансовых торговых системах.
Что это даёт практически
Когда лог является источником истины, несколько вещей становятся проще.
Восстановление после сбоя - одна из них. Если система была недоступна несколько часов и пропустила события, она просто читает журнал с того места, где остановилась. Ничего не потеряно, порядок сохранён.
Аудит становится бесплатным. Вопрос "что произошло с этим заказом и когда" перестаёт требовать ручного расследования - история уже в журнале.
Добавление новой системы не требует изменений в существующих. Новый потребитель просто начинает читать лог. Ни одна из существующих систем не знает о нём и не обязана ему звонить.
Где модель работает хуже
Событийная модель не серебряная пуля. Она добавляет сложность там, где раньше её не было.
Если вам нужно текущее состояние объекта - вы должны либо всегда проигрывать весь лог, либо строить и поддерживать отдельные проекции (snapshots). Это дополнительная работа.
Схема событий требует дисциплины. Если сегодня событие называется "order_created" с одним набором полей, а через полгода кто-то поменял структуру без версионирования - старые потребители ломаются.
Для простых CRUD-систем, где нет сложных взаимодействий и аудит не важен, модель избыточна.
Как думать об этом при проектировании
Я смотрю на событийную модель не как на обязательную архитектуру, а как на инструмент, который стоит применять в конкретных ситуациях.
Несколько вопросов, которые помогают принять решение:
- Есть ли у нас несколько систем, которым нужно знать об одних и тех же изменениях?
- Бывают ли ситуации, когда данные записались в одном месте, но не попали в другое?
- Нужна ли нам история изменений - для аудита, для отладки, для аналитики?
- Часто ли мы добавляем новые системы или интеграции?
- Насколько критична согласованность данных в реальном времени - или допустимо небольшое отставание?
Если на большинство из этих вопросов ответ "да" - стоит смотреть на журнал событий как на центральный механизм, а не как на вспомогательный.
Переход не быстрый и не бесплатный. Но компании, которые прошли через него, редко хотят возвращаться к паутине двусторонних вызовов.