> Откуда брать данные для уведомлений (Python)

Уровень: middle · Роль: backend · Язык: Python · Категория: Технические вопросы

Компании: Международный аэропорт Шереметьево

Стек: Python

> Пример ответа

Короткий ответ

Данные для уведомлений берутся из трёх основных источников: события домена (domain events), изменения в БД (CDC, outbox pattern) и явные вызовы сервиса уведомлений из бизнес-логики. Основной подход - это outbox pattern: запись события в отдельную таблицу в той же транзакции, что и бизнес-изменение, затем отдельный процесс читает outbox и отправляет уведомления. Это гарантирует атомарность и исключает потерю уведомлений.

Подробное объяснение

Выбор источника данных зависит от требований к надёжности и архитектуре:

  • Синхронный вызов - сервис уведомлений вызывается напрямую из кода после выполнения бизнес-операции. Просто, но есть риск потери уведомления при сбое после коммита, а также связывание сервисов.
  • Domain events - бизнес-события публикуются в шину (Kafka, RabbitMQ), подписчик формирует уведомление. Хорошо для слабой связанности, но нужна гарантия доставки.
  • Outbox pattern - событие записывается в таблицу outbox в той же транзакции, что и основное изменение. Отдельный процесс (poller или CDC) читает outbox и отправляет событие в брокер или напрямую в сервис уведомлений. Это стандарт для надёжных систем.
  • CDC (Change Data Capture) - чтение изменений из WAL БД (например, Debezium). Позволяет не менять код приложения, но сложнее в настройке и отладке.

Ключевой момент - атомарность: уведомление не должно быть отправлено, если бизнес-операция не закоммичена, и не должно быть потеряно, если операция прошла успешно. Outbox решает обе проблемы.

На практике

Для middle-уровня важно показать понимание trade-off'ов:

  • Если система небольшая и требования к надёжности низкие - достаточно синхронного вызова или простого события в брокер.
  • Если критична гарантия доставки (платежи, заказы) - outbox обязателен.
  • Если уже используется CDC (например, для аналитики) - можно переиспользовать для уведомлений, но это добавляет сложность.
  • Для уведомлений по email/push обычно используется отдельный сервис, который принимает готовые шаблоны и данные, а не строит их сам.

Также стоит упомянуть: данные для уведомлений часто нужно обогащать (имя пользователя, ссылки), поэтому в событие кладут минимум - ID сущности и тип события, а сервис уведомлений сам делает запросы за дополнительными данными.

Пример кода

PYTHON
# Модель outbox записи
class OutboxEvent(Base):
id = Column(UUID, primary_key=True)
aggregate_id = Column(UUID, index=True)
event_type = Column(String)
payload = Column(JSONB)
created_at = Column(DateTime, default=datetime.utcnow)
processed_at = Column(DateTime, nullable=True)
# В бизнес-транзакции
def create_order(order_data):
with db.transaction():
order = Order(**order_data)
db.add(order)
db.add(OutboxEvent(
aggregate_id=order.id,
event_type="order.created",
payload={"order_id": str(order.id), "user_id": order.user_id}
))
# коммит происходит здесь - outbox и order атомарны
# Отдельный процесс-релей
def process_outbox():
events = db.query(OutboxEvent).filter(OutboxEvent.processed_at.is_(None)).limit(100)
for event in events:
try:
broker.publish(event.event_type, event.payload)
event.processed_at = datetime.utcnow()
db.commit()
except Exception:
db.rollback()
# retry с backoff

Как отвечать на собеседовании

Начни с короткого ответа, затем раскрой архитектурный контекст. Обязательно упомяни outbox pattern как основной надёжный подход. Покажи, что понимаешь разницу между гарантией доставки и идемпотентностью. Приведи пример, когда синхронный вызов оправдан, а когда нет. Если спросят про масштабирование - скажи про партиционирование outbox и конкурентную обработку с блокировками.

Что проверяет интервьюер

  • Понимание проблемы атомарности между бизнес-данными и уведомлением.
  • Знание паттернов интеграции (outbox, CDC, domain events).
  • Умение оценивать trade-off'ы в зависимости от требований.
  • Практический опыт: как обрабатывать дубликаты, сбои, retry.
  • Понимание, что уведомление - это отдельный сервис с собственными данными и шаблонами.

Типичные ошибки

  • Предложение отправлять уведомление сразу после коммита без outbox - теряется при сбое.
  • Игнорирование идемпотентности: повторная отправка при retry.
  • Кладка в событие всех данных для уведомления вместо ID - усложняет обогащение и нарушает слабую связанность.
  • Утверждение, что CDC решает все проблемы - на деле это сложная инфраструктура.
  • Забывают про обработку ошибок в outbox-релее: без retry и мониторинга уведомления будут теряться молча.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью