Перейти к основному содержимому

Кейс сервиса

Notification-сервис

Событийный сервис доставки: durable inbox, консьюминг at-least-once, ограниченные воркеры доставки и ретраи с backoff — спроектирован вокруг дубликатов, poison-сообщений и восстановления.

ЗапланированРантайм бэкенда: Нет развёрнутого рантайма — стадия спецификацииИсточник данных демо: Mock

Область применения
Бэкенд-кейс о надёжном потреблении событий и доставке исходящих уведомлений для демо-окружения zolotoy.dev.
Не входит в область
  • Не платформа рассылок и маркетинга.
  • Не конструктор email/HTML-шаблонов.
  • Не продукт агрегатной аналитики.
Инженерный фокус
Обработка at-least-once, durable-задачи, семантика ретраев/DLQ, ограниченные воркеры.

Инженерный фокус

Обработка at-least-once, durable-задачи, семантика ретраев/DLQ, ограниченные воркеры.

Текущая реализация

Бэкенд-реализации пока нет. Демо-модуль отображает планируемые потоки на детерминированных моках; содержимое ниже — предлагаемая граница, а не работающая система.

  • Current

    Бэкенд-реализации пока нет: демо отображает детерминированные MSW-сценарии запланированной модели событие → задача → попытки.

    • Спецификация Notification-сервиса (целевой контракт)docs/backend-specs/03_notification_service.mdzolotoy-dev-frontend (this repository)проверено 2026-09-17

Целевая архитектура

  • Target

    Durable inbox с дедупликацией по ID события, чтобы доставка at-least-once от брокера никогда не приводила к двойной обработке.

    • Спецификация Notification-сервиса (целевой контракт)docs/backend-specs/03_notification_service.mdzolotoy-dev-frontend (this repository)проверено 2026-09-17
  • Target

    Транзакционное создание задач: задачи доставки фиксируются атомарно с коммитами inbox, поэтому падение не теряет и не осиротивает уведомление.

    • Спецификация Notification-сервиса (целевой контракт)docs/backend-specs/03_notification_service.mdzolotoy-dev-frontend (this repository)проверено 2026-09-17
  • Target

    Ограниченный пул воркеров с записями по попыткам, экспоненциальный backoff с джиттером, терминальные состояния dead-задач и восстановление брошенной работы на основе аренды (lease).

    • Спецификация Notification-сервиса (целевой контракт)docs/backend-specs/03_notification_service.mdzolotoy-dev-frontend (this repository)проверено 2026-09-17

Архитектура / основной поток

Целевая
  • Order-сервисПубликует события заказов через outbox
  • KafkaТранспорт событий (планируемая инфраструктура)
  • Inbox + дедупликацияИдемпотентное потребление событий
  • Задачи доставкиТранзакционные записи с попытками
  • Воркеры доставкиОграниченная конкурентность, backoff, lease
  • Email-провайдерВнешний API
  • события заказов: order → kafka (план)
  • консьюминг at-least-once: kafka → inbox (план)
  • транзакционное создание задач: inbox → jobs (план)
  • lease + записи попыток: jobs → worker (план)
  • отправка + запись результата: worker → provider (план)
Целевой поток уведомлений: события → durable-задачи доставки.

Инженерные решения

Везде at-least-once; дедупликация — ответственность потребителя

Целевой дизайн: брокер и воркеры гарантируют только at-least-once. Inbox дедуплицирует по ID события, а запись результата отправки идемпотентна.

Kafka DLQ и dead-задачи доставки — разные механизмы

Целевой дизайн: DLQ уровня брокера обрабатывает структурно необрабатываемые сообщения; dead-задачи уровня приложения — отклонённые провайдером или постоянно падающие доставки со своими политиками ретраев.

Lease-аренда восстанавливает брошенные задачи

Целевой дизайн: воркер держит lease с ограниченным сроком; при падении lease истекает и задачу подхватывает другой воркер. Дубликаты «отправка удалась, потом падение» решаются идемпотентной записью результата.

Надёжность / сценарии отказа

Дубликаты событий
Один и тот же ID события, доставленный дважды (ретрай брокера, rebalance консьюмера), должен закоммититься в inbox один раз; вторая копия подтверждается как уже обработанная.
Poison-сообщения
Сообщения, постоянно падающие на десериализации или валидации, не должны блокировать партицию: ограниченные ретраи, затем dead-letter с записанной причиной.
Временные против постоянных ошибок провайдера
429/5xx/таймауты ретраятся с backoff и джиттером; 4xx-ошибки валидации провайдера терминальны — задача уходит в dead с сохранённой причиной провайдера.
Успешная отправка, затем падение процесса
Провайдер принял письмо, но воркер умер до записи результата: ретрай даёт дубликат письма. Ограничивается ключами идемпотентности, где провайдер их поддерживает, и честной формулировкой «at-least-once».
Брошенные задачи в processing
Задачи, застрявшие в «processing» после смерти воркера, забираются повторно после истечения lease; число циклов перехвата ограничено до объявления задачи dead.

Доказательства

  • Спецификация Notification-сервиса (целевой контракт)docs/backend-specs/03_notification_service.mdzolotoy-dev-frontend (this repository)проверено 2026-09-17

Интерактивное демо

Следующая веха: События заказов → Notification

Transactional outbox/контракт событий, inbox/jobs, воркеры доставки, ретраи и восстановление.

Критерии приёмки (план):

  • Записи outbox коммитятся атомарно с изменениями состояния заказа
  • Дубликат события фиксируется в inbox один раз