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). Доставка даже при закрытом приложении.
Transactional и marketing. SendGrid, SES, Mailgun.
SMS
Twilio, Vonage. 2FA, критические алерты.
In-App / WebSocket
Real-time доставка при открытом приложении.
Требования
Функциональные
- FR1Отправка push, email, SMS, in-app уведомлений
- FR2Поддержка шаблонов с персонализацией
- FR3Настройки предпочтений пользователя
- FR4Отложенная отправка (scheduled)
- FR5Rate limiting и batching
Нефункциональные
- NFR110M+ уведомлений в день
- NFR2Soft real-time: доставка за секунды
- NFR3At-least-once delivery (с дедупликацией)
- NFR499.9% availability
High-Level Architecture
High-Level Architecture
Каналы цветовые: Push (blue), Email (green), SMS (amber)
Services
Triggers
Notification Service
Routing + templates
Message Queue
Kafka / SQS
Push Worker
APNs + FCM
Email Worker
SendGrid / SES
SMS Worker
Twilio / Vonage
APNs
Apple
FCM
SendGrid / SES
Email providers
Twilio
SMS provider
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 — оба типа в одном сообщении
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
| Column | Type | Description |
|---|---|---|
| user_id | BIGINT | FK to users |
| device_token | VARCHAR(255) | APNs/FCM token |
| platform | ENUM | ios, android, web |
| app_version | VARCHAR(20) | Для feature flags |
| last_active_at | TIMESTAMP | Для очистки stale токенов |
| created_at | TIMESTAMP | Дата регистрации |
Важно: Обрабатывайте 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?
• Как приоритизировать критические алерты?
