Спроектируйте сервис уведомлений
Вопрос
Спроектируйте сервис уведомлений: другие сервисы просят уведомить пользователя, а он получает push, email или SMS в зависимости от настроек.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Требования: каналы push, email, SMS; настройки и отписки пользователя, тихие часы, шаблоны; транзакционные (код входа) срочно, маркетинговые массово; без дублей, с повторами при сбоях
Оценка нагрузки: 50 млн пользователей по 5 уведомлений в день ≈ 250 млн в сутки ≈ 3 000 RPS в среднем; маркетинговая рассылка на 10 млн за час ≈ 3 000 RPS сверху; лимиты провайдеров SMS и email
API: POST /notifications {user_id, type, data, idempotency_key, priority}; GET /users/{id}/preferences; PUT /users/{id}/preferences
Данные: настройки пользователей и токены устройств в PostgreSQL, шаблоны в БД, журнал отправок (статусы) в ClickHouse или партиционированной таблице
Компоненты: API приёма, сервис маршрутизации (настройки, шаблон, канал), отдельные очереди по каналам и приоритетам, воркеры каналов с адаптерами провайдеров (APNs, FCM, SMTP, SMS-шлюзы)
Узкие места: медленные и падающие провайдеры (ретраи с backoff, DLQ, circuit breaker, резервный провайдер), дубли (ключ идемпотентности), массовые рассылки не должны задерживать срочные, rate limit под лимиты провайдеров, протухшие токены устройств
Что могут спросить следом
- Как сделать, чтобы рассылка не задержала код входа?
- Как избежать двойного SMS?
- Как обрабатывать отписки?
Разбор
Требования: три канала, настройки пользователя, тихие часы, шаблоны. Различаю срочные транзакционные уведомления, например код подтверждения, и массовые маркетинговые. Нагрузка: 250 млн в сутки, это около 3 000 RPS в среднем, но рассылки дают пики, а у SMS и email провайдеров есть свои лимиты. API: сервисы шлют POST с ключом идемпотентности и приоритетом. Сервис маршрутизации читает настройки, выбирает каналы, рендерит шаблон и кладёт задачи в очереди по каналу и приоритету, поэтому рассылка на 10 млн не стоит в одной очереди с кодами входа. Воркеры каналов зовут провайдеров, соблюдают их лимиты, ретраят с backoff, при длительном отказе переключаются на резервного провайдера, безнадёжное уходит в DLQ. Дедупликация по ключу идемпотентности через SET NX в Redis. Журнал статусов пишу в ClickHouse для аналитики доставок. Невалидные токены устройств удаляю по ответам APNs и FCM.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.