Обновлено: 23 июня 2026 г. в 00:45

Notification System

средний

Классический кейс про систему уведомлений: push, email и SMS, управление токенами устройств, гарантии доставки и повторные попытки при сбоях.

Система уведомлений усложняется не в момент отправки одного сообщения, а тогда, когда одно событие нужно надёжно разложить по многим пользователям, каналам и устройствам.

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

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

Бюджет задержек

Для каждого канала нужно заранее определить допустимое время доставки и поведение системы, если канал перестаёт в него укладываться.

Распределение по каналам

То, как одно событие раскладывается по получателям и каналам, напрямую влияет на масштабируемость и цену всей системы.

Состояние пользователя

Нужно явно учитывать подключённые устройства, quiet hours, порядок доставки и актуальные пользовательские настройки.

Мягкая деградация

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

Система уведомлений становится задачей про распределённые системы в тот момент, когда одно событие нужно корректно доставить многим пользователям, в несколько каналов и на разные устройства — с учётом приоритета, предпочтений и текущего состояния каждого канала. Перечислить push, email и SMS недостаточно: на интервью ждут, что вы назовёте гарантию доставки, стратегию повторных попыток, защиту внешних провайдеров от перегрузки и понятный путь деградации, когда один из каналов начинает отказывать.

Chapter 7

Acing SDI: Notification

Разбор кейса в книге Zhiyong Tan

Читать обзор

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

Push на мобильных устройствах

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

Email

Транзакционные и маркетинговые письма. SendGrid, SES, Mailgun.

SMS

Twilio, Vonage. 2FA и критические оповещения.

Уведомления в приложении

Доставка внутри приложения и через постоянное соединение, пока пользователь онлайн.

Требования

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

  • FR1
    Отправка push-уведомлений, email, SMS и уведомлений внутри приложения
  • FR2
    Поддержка шаблонов с персонализацией
  • FR3
    Настройки предпочтений пользователя
  • FR4
    Отложенная отправка по расписанию
  • FR5
    Ограничение частоты и пакетирование похожих уведомлений

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

  • NFR1
    10 млн+ уведомлений в день
  • NFR2
    Доставка в пределах нескольких секунд
  • NFR3
    Доставка по модели «как минимум один раз» с дедупликацией
  • NFR4
    Доступность 99,9%

Архитектура верхнего уровня

Архитектура верхнего уровня

Цветом выделены каналы доставки: Push (синий), Email (зелёный), SMS (янтарный)

Push-каналEmail-каналSMS-каналОбщий путь обработки

Бизнес-сервисы

Общий контур

Создают события

Сервис уведомлений

Общий контур

Маршрутизация и шаблоны

Очередь сообщений

Общий контур

Kafka / SQS

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

Push-обработчики

Push

APNs + FCM

Email-обработчики

Email

SendGrid / SES

SMS-обработчики

SMS

Twilio / Vonage

APNs

Push

Apple

FCM

Push

Google

SendGrid / SES

Email

Почтовые провайдеры

Twilio

SMS

SMS-провайдер

Доставка в пределах секунд
At-least-once и дедупликация
Горизонтальное масштабирование

Apple Push Notification Service (APNs)

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

APNs работает поверх постоянного мультиплексированного соединения и поддерживает аутентификацию по сертификату или токену.

Провайдер → APNs → устройство

POST /3/device/<device_token>

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

  • Device Token — уникальный токен устройства, который может меняться
  • Полезная нагрузка — JSON-пакет до 4 KB с полями alert, badge и sound
  • Priority — 10 для немедленной доставки или 5 для режима энергосбережения
  • Срок действия — время жизни для устройств, которые сейчас не в сети
  • Collapse ID — позволяет заменить предыдущее уведомление той же группы

Пример полезной нагрузки для APNs

{
  "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

FCM поддерживает Android, iOS и web-клиенты. Для отправки используется API версии v1 с аутентификацией через стандарт авторизации.

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

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

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

Пример запроса FCM версии v1

{
  "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"
      }
    }
  }
}

Связанный кейс

Chat System

Доставка в реальном времени через постоянное соединение

Читать обзор

Управление токенами устройств

На токенах устройств система ломается тихо: они меняются, устройства уходят офлайн, а у одного пользователя обычно несколько устройств и клиентских приложений. Если реестр не отслеживает это, push уходит в никуда, а метрика доставки выглядит нормально.

Таблица реестра устройств

КолонкаТипОписание
user_idBIGINTСсылка на пользователя
device_tokenVARCHAR(255)Токен APNs или FCM
platformENUMios, android, web
app_versionVARCHAR(20)Версия приложения для совместимости и поэтапного запуска функций
last_active_atTIMESTAMPПомогает очищать неактуальные токены
created_atTIMESTAMPДата регистрации

Важно: обрабатывайте обратную связь от APNs и FCM о недействительных токенах. Регулярно очищайте неактуальные токены устройств, которые давно не появлялись в системе.

Настройки пользователя

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

  • Global — включить или выключить все уведомления
  • Channel — управлять push, email и SMS по отдельности
  • Category — разделять маркетинговые, транзакционные и социальные уведомления
  • Quiet Hours — задавать тихие часы и временные ограничения

Ограничение частоты

  • Лимит N уведомлений в час или день
  • Объединение похожих уведомлений в один пакет
  • Отдельная приоритетная очередь для критических оповещений

Архитектура очередей сообщений

Kafka или SQS развязывает сервисы по времени и помогает сохранить понятную гарантию доставки. Для каждого канала обычно выделяют свой топик и отдельную группу потребителей.

Топики:
├── notifications.push.ios      → Обработчики push-канала (APNs)
├── notifications.push.android  → Обработчики push-канала (FCM)
├── notifications.email         → Email-обработчики
├── notifications.sms           → SMS-обработчики
├── notifications.realtime      → Обработчики постоянных соединений
└── notifications.dlq           → Очередь ошибочных сообщений

Партиционирование: по user_id для порядка в рамках одного пользователя
Хранение: 7 дней (для повторных попыток и разбора инцидентов)

Rate Limiting

Rate Limiter

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

Читать обзор

Гарантии доставки

At-Most-Once

Отправили и забыли. Самый простой подход.

⚠️ Сообщения могут теряться

Как минимум один раз

Повторные попытки с подтверждением. Требует дедупликации.

✓ Подходит для большинства практических случаев

Exactly-Once

Идемпотентный ключ плюс транзакционный журнал исходящих событий.

Сложно, дорого и нужно нечасто

Стратегия дедупликации

// Идемпотентный ключ = digest(user_id + notification_type + content_digest + date)

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

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

Повторные попытки и обработка ошибок

Стратегия повторных попыток

  • Экспоненциальная пауза: 1s → 2s → 4s → 8s...
  • Максимум повторов: 3-5 попыток
  • Случайный разброс: смещение, чтобы размазать нагрузку
  • Размыкатель цепи: при массовых ошибках у провайдера

Классификация ошибок

  • Повторяемые: 429, 503, таймаут сети
  • Неповторяемые: 400, 401, недействительный токен
  • Очередь ошибочных сообщений: после исчерпания повторных попыток

Patterns

Release It!

Размыкатель цепи и другие паттерны устойчивости

Читать обзор

Масштабирование

Горизонтальное масштабирование

• Обработчики без локального состояния — автомасштабирование по глубине очереди

• Разбиение по user_id для сохранения порядка доставки одному пользователю

• Отдельные пулы обработчиков для каждого канала

Ограничения провайдеров

• APNs: мультиплексированное соединение, около 4000 запросов в секунду на соединение

• FCM: до 600 тыс. сообщений в минуту на платных планах

• Используйте пул соединений

Массовые уведомления: для рассылки на миллионы пользователей используйте группы рассылки FCM или раскладывайте отправку через Kafka с пакетной обработкой.

Наблюдаемость

Метрики

  • Отправленные и неуспешные уведомления по каждому каналу
  • Задержка доставки на 50-м и 99-м перцентилях
  • Глубина очереди и отставание потребителей
  • Доля ошибок у внешних провайдеров

Логи

  • Структурированные логи с корреляционным идентификатором
  • Коды ответов провайдеров
  • Применённые пользовательские настройки

Оповещения

  • Всплеск ошибок
  • Рост очереди
  • Деградация внешнего провайдера

Что важно проговорить на интервью

Что показать в ответе

• Чем отличаются APNs и FCM

• Как устроен жизненный цикл device token

• Когда достаточно доставки как минимум один раз и зачем нужна дедупликация

• Как защищать внешних провайдеров лимитами запросов

• Где применять пользовательские настройки и quiet hours

Типичные дополнительные вопросы

• Как сохранить порядок уведомлений для одного пользователя?

• Как обработать массовую рассылку на 10 млн пользователей?

• Как избежать дублирующихся уведомлений?

• Как приоритизировать критические оповещения?

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

  • Chat System - даёт прикладной сценарий доставки в реальном времени, где уведомления внутри приложения и постоянные соединения становятся частью основного пользовательского потока.
  • Событийно-ориентированная архитектура - объясняет асинхронную модель обработки событий, на которой обычно строят конвейер доставки уведомлений.
  • Distributed Message Queue - углубляет устройство очередей, партиционирование и гарантии доставки для масштабной рассылки уведомлений.
  • Rate Limiter - нужен для защиты внешних провайдеров, таких как APNs, FCM, SMS- и email-шлюзы, от всплесков нагрузки и злоупотреблений.
  • Паттерны устойчивости - дополняет подходы к повторным попыткам, очереди ошибочных сообщений и мягкой деградации при сбоях каналов доставки.
  • Протокол веб-сокетов - покрывает канал доставки внутри приложения через постоянное соединение и обновления с низкой задержкой.
  • Release It! (short summary) - даёт практики инженерной устойчивости для надёжной доставки уведомлений в рабочей системе.

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