#кейс. Event Sourcing в масштабе.

Event Sourcing в масштабе: где проходит граница чистой архитектур

Представим реальный масштаб.

1200 сервисов. 30 команд. Нужно собирать события пользователей : аутентификация, платеж, перевод и т.д.

Эти события нужны двум разным системам: — система мониторинга ошибок и проактивных действий — система безопасности (борьба с мошенничеством)

Контексты разные. Потребности разные. Пересечение данных — около 50%.

Обе системы принимают события через Kafka.

И дальше возникает ключевой архитектурный вопрос:

> Каждый сервис должен публиковать события сразу в две Kafka  ?

> или сбор и разделение нужно вынести в отдельный слой?

Наивный вариант

Самый очевидный путь —  в каждом сервисе реализовать две публикации: — Kafka A — Kafka B

Локально это выглядит просто. Глобально — почти всегда становится проблемой.

Альтернатива: единый поток и Projector

Мы смотрим на сервис как на владельца доменных событий.

Сервис: — пишет данные в БД — публикует один гарантированный поток событий (через outbox)

Дальше появляется отдельный слой — Projector: — читает события — трансформирует — фильтрует — маршрутизирует — публикует в нужные Kafka-кластеры

Это решение выглядит «архитектурно красиво». Но важно честно разобрать плюсы и риски.

Плюсы: почему это чисто

1. Чёткая граница ответственности Сервис отвечает только за: — доменную модель — корректность событий

Вопросы «куда и в каком виде можно отдавать данные» уезжают из сервиса.

Это сильная clean boundary.

2. Безопасность и комплаенс Логика: — маскирования — фильтрации — разрешённых полей

находится в одном месте, а не размазана по 1200 кодовых баз.

3. Стабильность контрактов Можно разделить: — внутренний канонический формат событий — внешние витрины под конкретные системы

Эволюция схем становится управляемой.

Минусы: где архитектура может сломаться

Чистота здесь не бесплатная.

1. Риск «интеграционного монолита» Если Projector начинает: — принимать бизнес-решения — агрегировать смысл — «умно» интерпретировать события

он быстро превращается в монолит интеграций.

2. Зоопарк трансформаций Если разные команды начинают: — добавлять свои правила — усложнять логику — решать локальные задачи

архитектура деградирует.

Вывод по чистоте

Подход остаётся чистым только при жёстком ограничении роли Projector.

Допустимо: — field mapping — фильтрация — версионирование — маскирование — маршрутизация

Недопустимо: — предметная логика — бизнес-правила — принятие решений за домен

Почему «публиковать в две Kafka из каждого сервиса» чаще хуже

На масштабе 1200 сервисов этот вариант почти всегда проигрывает по TCO.

1. Dual-write и консистентность Сервису нужно гарантировать: — DB — Kafka A — Kafka B

Даже с outbox это означает: — два outbox’а или — один outbox и два независимых продьюсера

Риски: — в одну Kafka ушло, в другую нет — сложные ретраи — дедупликация — расследования инцидентов

2. Операционная нагрузка ×1200 Удваивается всё: — конфиги — security / ACL / TLS — клиентские библиотеки — версии — инциденты «падает внешний кластер»

И всё это — на 30 команд.

3. Безопасность и доверие

Если одна из Kafka — другой домен доверия,  ключевое правило  минимизация данных.

Держать логику «что можно наружу»

в 1200 сервисах = почти гарантированный дрейф.

4. Эволюция контрактов Схемы, версии, совместимость

намного проще: — централизовать — контролировать — версионировать

в одном слое, чем синхронизировать изменения в сотнях сервисов.

Итоговый вывод

В масштабе: — 1000+ сервисов — десятков команд — разных контекстов потребления

модель: один доменный поток → централизованный Projector → несколько Kafka

чаще всего выигрывает по: — управляемости — безопасности — стоимости владения

Но это работает только при дисциплине.

Projector — это инфраструктурный слой,  а не место для бизнес-логики.

Как только эта граница нарушается чистая архитектура заканчивается.

Мой канал - https://t.me/manager_dot_exe

#кейс. Event Sourcing в масштабе. | Сетка — социальная сеть от hh.ru