Event-Driven Architecture на AWS: где ломается поток
Сервисы, начинавшиеся как независимые модули, быстро обрастают синхронными вызовами: оформление заказа дёргает оплату, склад, уведомления и аналитику прямо в обработчике запроса. Один упавший получатель останавливает всю цепочку, а на пиковой нагрузке часть событий не доходит — издатель получает таймаут, повторяет вызов и множит давление на уже перегруженный сервис.
Разбор такого инцидента растягивается на дни, потому что единой шины и схемы потоков нет. Непонятно, где событие потерялось, обработал ли его получатель и в каком порядке шли повторы. Связность сервисов при этом растёт квадратично: каждый новый потребитель требует отдельной интеграции с каждым издателем, а правка контракта превращается в согласование между командами.
Событийно-ориентированная архитектура разворачивает эту схему: издатель публикует событие один раз, маршрутизацию берёт на себя шина. В EventBridge правила отбора строятся по источнику, типу и содержимому события — получатели не знают друг о друге, а новый потребитель подключается отдельным правилом, без правок в коде издателя.
Потеря событий переходит из класса «иногда пропадает» в разряд управляемых сбоев: шина буферизует поток на пике, повторяет доставку по расписанию и уводит необработанные сообщения в отдельную очередь для разбора. Архив событий позволяет воспроизвести поток за нужный период, а реестр схем фиксирует формат сообщения — несовместимое изменение ловится при публикации, а не в момент отказа у получателя.
Что даёт событийный обмен: измеримые эффекты
Эффект событийного обмена проверяется не по презентации, а по чек-листу: время реакции на бизнес-событие, число правок в сервисе-источнике при подключении нового потребителя, доля сбоев, которые не дошли до пользователя, и время восстановления потока после отказа.
Время реакции на бизнес-событие вместо ночной выгрузки
Классическая схема — регламентная выгрузка раз в сутки: заказ уходит на склад, когда отработает пакетная задача, а статус в клиентском кабинете обновляется к утру. Событийная маршрутизация в Amazon EventBridge сокращает разрыв до секунд: публикация в шину и доставка подписчику идут в одном цикле, а правила фильтрации отсекают лишнее до попадания в очередь потребителя. Проверяем эффект по времени от действия клиента до изменения в смежных системах — оно падает с часов до единиц секунд.
Слабая связность: добавление потребителя без правок источника
Источник публикует событие и не знает, кто его читает. Новый потребитель — аналитика, антифрод, уведомления — подключается подпиской, а не доработкой сервиса-источника.
- Контракт события описывает тип, версию и полезную нагрузку.
- Маршрутизация и фильтры настраиваются на стороне шины.
- Недоставленные сообщения уходят в очередь повторов, а не теряются молча.
Вместе с пакетными выгрузками уходит отдельный класс отказов — рассинхрон данных между системами: событие либо доставлено, либо зафиксировано как ошибка с повтором. Отраслевые обзоры называют срыв обмена между системами одной из самых дорогих причин простоя; измеряем его не деньгами, а долей операций, вставших за час, и временем до восстановления потока.
Архитектура маршрутизации: варианты и ограничения
Выбор режима маршрутизации определяет, что произойдёт с событием, когда получатель недоступен или отклонил сообщение. Ниже — три рабочие схемы и их поведение при отказах.
Правила отбора и фильтрация по атрибутам
Правила маршрутизации задаются декларативно — по источнику и атрибутам события. Фильтрация на стороне шины отсекает лишний трафик до вызова получателя, поэтому подписчик получает только свой срез, а не весь поток. Режимы подписки при этом различаются: адресная доставка, широковещательная рассылка и конкурентное чтение, когда поток делят несколько экземпляров сервиса.
Что делать с сообщением, которое не удалось доставить
Гарантия доставки не значит «доставим всегда» — она значит, что судьба каждого сообщения известна. После исчерпания повторов событие уходит в очередь недоставленных сообщений, откуда его переигрывают вручную или разбирают причину отказа. Без этого контура отказ получателя превращается в тихую потерю данных.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Прямая доставка точка-точка | Один производитель, один потребитель, поток умеренный | Нет буфера при недоступности получателя; новый потребитель требует правок у отправителя |
| Центральная шина с правилами отбора | Много потребителей, у каждого свой срез событий | Нужна дисциплина схемы событий; ошибка в правиле тихо отсекает подписчика |
| Гибрид: шина плюс очередь недоставленных | Сценарии, где потеря события недопустима | Больше компонентов: нужен регламент разбора и переигровки очереди |
Этапы внедрения: от схемы потоков до передачи
Переход на событийную архитектуру в AWS начинаем не с настройки шины, а с инвентаризации потоков: сначала фиксируем текущее состояние, затем проектируем схему событий и только потом включаем маршрутизацию в рабочем контуре. Пропущенный аудит обходится дороже самого переноса — скрытые связи между сервисами всплывают под нагрузкой, когда откат стоит дорого.
Как выглядит аудит потоков
Это не опрос разработчиков, а трассировка: смотрим, какой сервис публикует событие, кто его читает, что происходит при повторной доставке. На выходе — карта потоков с владельцем, частотой и критичностью каждого события плюс список «мёртвых» подписок и дублирующих маршрутов, которые отключаем до переезда.
- Инвентаризация потоков событий — карта источников, подписчиков и владельцев, границы доменов.
- Проектирование схем событий — единый контракт, обязательные поля, версионирование и обратная совместимость.
- Настройка шины и правил маршрутизации — фильтры, целевые очереди, повторы, очередь недоставленных сообщений.
- Разграничение доступов — отдельные роли на публикацию и подписку, изоляция контуров, запрет широких прав.
- Проверка на сбоях и повторах — гасим подписчика, рвём связь, дублируем событие и смотрим, как система восстанавливается.
- Передача с обучением — документация, разбор инцидентов, дежурная смена учится читать карту потоков.
Приёмочные проверки перед запуском
Запуск готов, когда повтор события не создаёт вторую запись, недоставленные сообщения возвращаются в работу, а новый сервис подключается к шине без правок в чужих репозиториях. Отдельно прогоняем отказ узла: система должна деградировать предсказуемо, а не терять события молча.
Конфигурации, схемы событий и регламенты передачи
Комплект, который остаётся у заказчика после запуска, — рабочая документация, а не презентация: по ней дежурная смена разбирает инцидент без автора интеграции. В шине на базе Amazon EventBridge конфигурация хранится отдельно от кода сервисов, поэтому маршрутизацию и права можно менять без релиза самих потребителей.
Политики доступа и роли сервисов
- Конфигурация шины: правила маршрутизации, фильтры по типу и источнику события, отдельные каналы под критичные и фоновые потоки.
- Описание схем событий: состав полей, версия контракта и правило обратной совместимости — добавление поля не ломает существующих потребителей.
- Политики доступа: какая роль сервиса что публикует и что читает, ограничение по каналам, разделение сред и отдельные права для отладочных подписок.
Документация и регламенты сопровождения
- Карта потоков: кто чьи события потребляет, где стоит буферизация и на каком участке включается повторная обработка.
- Регламент повторной обработки: число попыток, интервал между ними, условия перевода события в очередь необработанных и порядок ручного перезапуска.
- Порядок разбора сбоев и инструкции для дежурной смены: как отключить потребителя и переиграть поток без потери событий.
- Документация интеграции: как подключить новый сервис и какие проверки пройти до вывода в продуктивную среду.
Кейс: как выровняли поток заказов между системами
Что было до: ручная сверка и ночные выгрузки
Интернет-магазин, склад и биллинг жили на разных платформах, обмен шёл ночными выгрузками в CSV. Заказ мог зависнуть на часы: если файл не собирался, о расхождении узнавали от клиента, а не от системы — поддержка начинала разбор раньше, чем инженеры.
Потери доходили до 4% позиций в неделю, каждое расхождение сверяли руками по двум таблицам. В пик распродажи выгрузки не успевали, и часть заказов ждала следующего окна — задержка зависела от календаря, а не от нагрузки на сервисы.
Что стало после: показатели и оставшиеся ограничения
Мы заменили пакетный обмен на событийную шину: система публикует факт — «заказ создан», «оплата подтверждена», «отгрузка собрана» — а подписчики получают его сразу. Шиной стал AWS EventBridge с правилами маршрутизации и очередью недоставленных сообщений: событие либо доходит до адресата, либо попадает в разбор, но не исчезает молча.
Показатели после: доля потерянных событий — 0 за квартал против 4%; время реакции на заказ — минуты вместо часов; ручных разборов — 2 в неделю вместо 30, и те из-за грязных данных источника, а не доставки.
Ограничения остались честные. Глобальный порядок событий не гарантирован — обработчики сделали идемпотентными по номеру заказа, повтор не создаёт дубль. Учётная система, которая не публикует изменения сама, по-прежнему опрашивается по расписанию. Схема события версионируется: без этого смена формата ломает подписчиков. Похожий проект мы описывали публично — грабли ровно те же.
Чем событийный обмен отличается от пакетной выгрузки?
Пакетная выгрузка работает по расписанию: источник раз в час или раз в сутки формирует срез данных и передаёт его целиком. Событийный обмен устроен иначе — источник публикует факт изменения в тот момент, когда оно произошло, а получатели забирают его сами, без опроса и без общего расписания. Разница в архитектуре сразу проявляется в трёх местах: задержка реакции, цена изменения схемы и поведение при сбое на стороне получателя.
Задержка реакции в пакетном режиме равна периоду выгрузки: изменение, попавшее сразу после прогона, ждёт следующего. Витрины и отчёты живут с лагом в часы, а сценарии, где важна быстрая реакция — пересчёт остатков, уведомления, проверка платежа, — приходится закрывать отдельной синхронной логикой поверх. Режим реального времени сокращает задержку до секунд: маршрутизацию событий между сервисами удобно держать на управляемой шине вроде AWS EventBridge, где правила подписки описываются декларативно, а не кодом на стороне каждого потребителя.
Изменение схемы данных бьёт по обоим режимам, но по-разному. В пакете достаточно поправить один запрос — все потребители увидят новый набор полей одновременно, зато связаны жёстко: правка ломает отчётность до тех пор, пока её не согласуют со всеми. В событийном обмене контракт события становится публичным интерфейсом: поля добавляют с версионированием, старые подписчики продолжают работать, но каждый обработчик нужно проверить на совместимость.
Сбой получателя — самое показательное расхождение. Пакетная выгрузка идемпотентна по природе: упал приём, следующий прогон принесёт тот же срез. Событийный поток такой роскоши не даёт — нужны идемпотентные обработчики, повторные доставки с нарастающей паузой и очередь недоставленных сообщений, иначе события теряются молча.
Пакетный режим остаётся разумным выбором там, где реакция не критична: ночные сверки, тяжёлая аналитика, регулярные выгрузки в хранилище, обмен с системами, которые в принципе не умеют принимать поток. Он проще в эксплуатации и предсказуемее по нагрузке. Событийный обмен выигрывает там, где бизнес-процесс идёт минутами, а не сутками, и где потерянное изменение стоит дороже, чем сложность инфраструктуры.
Технические сомнения: надёжность, повторы, доступы
Событийная шина доставляет сообщение минимум один раз — повтор это плата за устойчивость к падениям получателя, а не дефект. Ниже пять вопросов, которые команды задают нам первыми.
Что будет, если получатель недоступен?
Событие повторяется с растущей паузой, пока получатель не поднимется, затем уходит в очередь необработанных. Оттуда его возвращают вручную, а рост очереди виден на панели мониторинга.
Как не обработать событие дважды?
Обработчики делают идемпотентными по ключу события: повтор с тем же ключом распознаётся и не меняет состояние. Журнал применённых ключей храним там, где важна смена статуса или платёж.
Можно ли подключить работающую систему?
Да, переходным слоем: шина получает события параллельно с текущим потоком, обработчики идут в режиме наблюдения. Через несколько дней без расхождений старый поток отключаем.
Как разграничить доступ к отдельным потокам?
Права вешаем на правила шины и роли приложений: каждый сервис публикует и читает только свои типы событий. Секреты выдаём на сервис, а не на команду.
Кто отвечает за разбор сбоя?
Архив с поиском по ключу и времени позволяет найти конкретное событие и повторить его точечно. Метрики задержки и доли ошибок сводим на один экран, чтобы дежурный видел отклонение раньше бизнеса; разбор инцидентов ведём мы.
Обсудим вашу схему событий и вернёмся с планом
Чтобы вернуться с оценкой интеграции, а не с общими формулировками, нам нужен ваш контур как он есть: состав систем, формат событий и места, где сейчас рвётся. Опишите задачу в свободной форме — этого достаточно, чтобы начать разбор.
Что прислать для оценки:
- перечень систем-источников и потребителей событий, включая внешние сервисы и очереди;
- пример реального события или выгрузку из журнала — формат, атрибуты, объём в сутки;
- узкие места, которые уже заметны: задержки, дубли, потерянные сообщения, ручной разбор отказов;
- требования к задержке доставки и порядку обработки для критичных потоков;
- правила фильтрации и маршрутизации, разделение сред и доступы между контурами;
- режим сопровождения шины: кто дежурит и как реагируем на сбой правила или отравленное событие.
В ответ вы получите схему потоков с точками отказа и буферами, план этапов — от переноса первых маршрутов до вывода старых и передачи шины на сопровождение — и оценку сроков. Дальше решение за вами: мы готовы стартовать с того участка, где эффект виден быстрее всего.
-
Событие как «сообщение обо всём». В один поток пихают и факт «заказ создан», и всю его карточку целиком — получатели разбирают лишнее, схема обрастает полями, и через месяц никто не может ответить, кто и зачем её расширил. Событие должно фиксировать свершившийся факт, а не пересказывать состояние системы.
-
Отсутствие единого словаря названий. Одна команда шлёт
OrderPaid, другая —payment_done, третья —оплата_прошла. Формально обмен работает, фактически каждый новый участник тратит недели на ручное сопоставление, а часть потоков тихо теряется. Регламент имён и схем согласуют до первой передачи, а не после. -
Событийный обмен «на всякий случай», без потребителя. Поток запускают, потому что «так современнее», а подписчиков у него нет. Нагрузка на маршрутизацию растёт, журнал пухнет, разбираться в нём некому — расходы на хранение и сопровождение растут, а пользы ноль.
-
Игнорирование повторов и порядка. Полагаются на то, что каждое событие придёт ровно один раз и строго по порядку. На практике дубли и перестановки — норма: оплата приходит после отгрузки, повтор списывает средства дважды. Обработчики делают повторяемыми, а порядок восстанавливают по ключу сущности, а не по времени получения.
-
Нет правил на «мёртвые» сообщения. Событие не прошло проверку схемы или упало у получателя — и остаётся лежать молча. Без отдельного места для неудачных и без понятного владельца такие случаи всплывают через месяцы, уже как расхождение в отчётности.
-
Секреты и доступы «по-простому». Ключи в открытом виде в конфигурации, у всех участников одни и те же права, отозвать доступ одному нельзя. При подключении нового подрядчика это превращается в переделку всех связей — вместо того чтобы выдать изолированную роль.
-
Схема меняется без обратной совместимости. Убирают поле или меняют его смысл, не предупредив подписчиков. Поток формально жив, но часть систем читает пустоту и молча пишет неверные данные — сбой обнаруживается на уровне итогов, а не на уровне обмена.
-
Смешение событий и команд. В один поток кладут и «это произошло», и «сделай вот это». Отправитель начинает ждать немедленного исполнения и зависит от получателя так же, как при прямом вызове — теряется сама выгода развязки.
Работаем на профессиональном оборудовании и настроенной маршрутизации, поэтому поток остаётся предсказуемым при росте числа участников — клиент получает стабильный результат без пересборки связей.







