Обновлено: 25 марта 2026 г. в 04:52

Notification System

medium

Push-уведомления (APNs, FCM), email, SMS: device token management, delivery guarantees, retry patterns.

Notification system становится сложным в тот момент, когда одно событие должно дойти до многих пользователей, каналов и устройств с разными правилами приоритета, ретраев и предпочтений.

Глава помогает связать fanout, очереди, шаблоны доставки, user preferences, provider isolation и идемпотентность в систему, которая выдерживает пики и деградацию внешних каналов.

В интервью и инженерных обсуждениях этот кейс полезен тем, что заставляет явно выбрать delivery semantics, стратегию деградации и границы critical user path.

Latency Budget

Каждый hop в критическом пути должен иметь чёткий тайм-бюджет и предсказуемое поведение.

Fanout Strategy

Выбор push/pull/hybrid напрямую влияет на масштабируемость и сложность системы.

Session State

Важно учитывать presence, reconnect, ordering и delivery semantics для клиента.

Graceful Degradation

При пиках нагрузок система должна понижать качество сервиса без массового отказа.

Notification System — критически важный компонент современных приложений. Она объединяет push-уведомления (iOS/Android), email, SMS, in-app сообщения и real-time WebSocket доставку. Эта задача часто встречается на System Design интервью, особенно в компаниях с большой пользовательской базой.

Chapter 7

Acing SDI: Notification

Разбор задачи в книге Zhiyong Tan

Читать обзор

Типы уведомлений

Push (Mobile)

APNs (iOS), FCM (Android). Доставка даже при закрытом приложении.

Email

Transactional и marketing. SendGrid, SES, Mailgun.

SMS

Twilio, Vonage. 2FA, критические алерты.

In-App / WebSocket

Real-time доставка при открытом приложении.

Требования

Функциональные

  • FR1
    Отправка push, email, SMS, in-app уведомлений
  • FR2
    Поддержка шаблонов с персонализацией
  • FR3
    Настройки предпочтений пользователя
  • FR4
    Отложенная отправка (scheduled)
  • FR5
    Rate limiting и batching

Нефункциональные

  • NFR1
    10M+ уведомлений в день
  • NFR2
    Soft real-time: доставка за секунды
  • NFR3
    At-least-once delivery (с дедупликацией)
  • NFR4
    99.9% availability

High-Level Architecture

High-Level Architecture

Каналы цветовые: Push (blue), Email (green), SMS (amber)

Push channelEmail channelSMS channelCore shared path

Services

Core

Triggers

Notification Service

Core

Routing + templates

Message Queue

Core

Kafka / SQS

Fanout по каналам доставки: Push / Email / SMS

Push Worker

Push

APNs + FCM

Email Worker

Email

SendGrid / SES

SMS Worker

SMS

Twilio / Vonage

APNs

Push

Apple

FCM

Push

Google

SendGrid / SES

Email

Email providers

Twilio

SMS

SMS provider

Soft real-time delivery
At-least-once + dedupe
Horizontal scaling

Apple Push Notification Service (APNs)

Архитектура APNs

APNs использует persistent HTTP/2 соединение с certificate-based или token-based аутентификацией.

Provider → APNs → Device

POST /3/device/<device_token>

Ключевые особенности

  • Device Token — уникальный ID устройства (меняется)
  • Payload — до 4KB JSON с alert, badge, sound
  • Priority — 10 (immediate) или 5 (power-saving)
  • Expiration — TTL для offline устройств
  • Collapse ID — замена предыдущего уведомления

APNs Payload Example

{
  "aps": {
    "alert": {
      "title": "New Message",
      "body": "You have a new message from John"
    },
    "badge": 5,
    "sound": "default",
    "mutable-content": 1  // для Notification Service Extension
  },
  "custom_data": {
    "conversation_id": "abc123"
  }
}

Firebase Cloud Messaging (FCM)

FCM Architecture

FCM поддерживает Android, iOS и Web. Использует HTTP v1 API с OAuth 2.0 аутентификацией.

POST /v1/projects/<project_id>/messages:send

Типы сообщений

  • Notification — FCM показывает автоматически
  • Data — приложение обрабатывает само
  • Hybrid — оба типа в одном сообщении
💡 Data messages дают полный контроль над отображением

FCM HTTP v1 Request

{
  "message": {
    "token": "device_registration_token",
    "notification": {
      "title": "New Order",
      "body": "Your order #1234 has been shipped"
    },
    "data": {
      "order_id": "1234",
      "click_action": "OPEN_ORDER_DETAIL"
    },
    "android": {
      "priority": "high",
      "ttl": "86400s"
    },
    "apns": {
      "headers": {
        "apns-priority": "10"
      }
    }
  }
}

WebSocket

Chat System

Real-time доставка через WebSocket

Читать обзор

Device Token Management

Управление device tokens — критически важная часть системы. Токены могут меняться, устройства — отключаться, пользователи — иметь несколько устройств.

Device Registry Table

ColumnTypeDescription
user_idBIGINTFK to users
device_tokenVARCHAR(255)APNs/FCM token
platformENUMios, android, web
app_versionVARCHAR(20)Для feature flags
last_active_atTIMESTAMPДля очистки stale токенов
created_atTIMESTAMPДата регистрации

Важно: Обрабатывайте feedback от APNs/FCM об invalid tokens. Регулярно очищайте stale токены (устройства, неактивные 30+ дней).

User Preferences

Уровни настроек

  • Global — вкл/выкл все уведомления
  • Channel — push, email, SMS отдельно
  • Category — marketing, transactional, social
  • Quiet Hours — временные ограничения

Frequency Capping

  • Max N уведомлений в час/день
  • Aggregation (bundling) похожих уведомлений
  • Priority queue для критических алертов

Message Queue Architecture

Kafka/SQS обеспечивает decoupling между сервисами и гарантию доставки. Каждый канал имеет свой топик и consumer group.

Topics:
├── notifications.push.ios      → Push Workers (APNs)
├── notifications.push.android  → Push Workers (FCM)
├── notifications.email         → Email Workers
├── notifications.sms           → SMS Workers
├── notifications.websocket     → WebSocket Workers
└── notifications.dlq           → Dead Letter Queue

Partitioning: по user_id для ordering per user
Retention: 7 дней (для retry и debugging)

Rate Limiting

Rate Limiter

Защита от перегрузки внешних провайдеров

Читать обзор

Delivery Guarantees

At-Most-Once

Fire and forget. Простейший подход.

⚠️ Потеря сообщений возможна

At-Least-Once

Retry с acknowledgment. Требует дедупликации.

✓ Рекомендуется для большинства случаев

Exactly-Once

Idempotency key + transactional outbox.

Сложно, дорого, редко нужно

Deduplication Strategy

// Idempotency Key = hash(user_id + notification_type + content_hash + date)

Redis SET with TTL:
  SETNX notification:dedupe:{idempotency_key} 1 EX 86400

Если ключ уже существует → skip отправку

Retry & Error Handling

Retry Strategy

  • Exponential Backoff: 1s → 2s → 4s → 8s...
  • Max Retries: 3-5 attempts
  • Jitter: случайная добавка для распределения нагрузки
  • Circuit Breaker: при массовых ошибках провайдера

Error Classification

  • Retryable: 429, 503, network timeout
  • Non-retryable: 400, 401, invalid token
  • DLQ: после исчерпания retries

Patterns

Release It!

Circuit Breaker и другие паттерны устойчивости

Читать обзор

Scaling Considerations

Horizontal Scaling

• Stateless workers — auto-scale по queue depth

• Partition по user_id для ordering guarantees

• Separate worker pools per channel

Provider Rate Limits

• APNs: HTTP/2 multiplexing, ~4000 req/s per connection

• FCM: 600K messages/min (платные планы)

• Используйте connection pooling

Broadcast Notifications: Для массовой рассылки (миллионы пользователей) используйте FCM Topics или fan-out через Kafka с batch processing.

Observability

Metrics

  • Notifications sent/failed per channel
  • Delivery latency (p50, p99)
  • Queue depth и consumer lag
  • Provider error rates

Logging

  • Structured logs с correlation ID
  • Provider response codes
  • User preferences applied

Alerting

  • Spike in error rates
  • Queue backlog growing
  • Provider degradation

Ключевые выводы для интервью

Покажите понимание

• Разница между APNs и FCM

• Device token lifecycle

• At-least-once vs exactly-once delivery

• Rate limiting провайдеров

• User preferences и quiet hours

Частые follow-up вопросы

• Как обеспечить ordering уведомлений?

• Как обработать broadcast на 10M пользователей?

• Как избежать duplicate notifications?

• Как приоритизировать критические алерты?

Связанные главы

  • Chat System - даёт прикладной real-time сценарий, где in-app и WebSocket уведомления формируют ключевую часть UX.
  • Event-Driven Architecture: Event Sourcing, CQRS, Saga - объясняет асинхронную модель обработки событий, на которой обычно строятся notification pipelines.
  • Distributed Message Queue - углубляет дизайн очередей, partitioning и delivery semantics для масштабной доставки уведомлений.
  • Rate Limiter - нужен для защиты внешних провайдеров (APNs/FCM/SMS/email) от burst-нагрузки и abuse.
  • Паттерны отказоустойчивости: Circuit Breaker, Bulkhead, Retry - дополняет retry/DLQ-подходы и стратегии деградации при сбоях каналов доставки.
  • WebSocket протокол - закрывает канал real-time in-app доставки с постоянным соединением и low-latency обновлениями.
  • Release It! (short summary) - даёт практики stability engineering для надёжной доставки уведомлений в проде.

Чтобы отмечать прохождение, включи трекинг в Настройки