Как сделать сервис уведомлений
Что проверяют
Умеете ли вы проектировать систему с ненадёжными внешними провайдерами: очереди, повторы, идемпотентность, приоритеты. Вопрос стоит в поведенческом блоке, поэтому следом обычно просят рассказать о своём проекте: что отправляли, в каком объёме, что ломалось.
Как отвечать
Начните с уточнений: какие каналы (email, SMS, push), объём в пике, допустимая задержка, нужна ли гарантия доставки. Затем каркас на Spring Boot:
- приём событий: сервис слушает доменные события из Kafka (
@KafkaListener) или принимаетPOST /notificationsи сразу отвечает202 Acceptedс идентификатором; - надёжная публикация: если событие рождается в бизнес-транзакции, нужен transactional outbox: запись в таблицу outbox в той же транзакции, дальше relay или Debezium переносит её в Kafka;
- обогащение: настройки пользователя (каналы, отписки, тихие часы), шаблоны и локаль;
- очереди по приоритетам: коды входа отдельно от маркетинга, чтобы массовая рассылка не задерживала коды;
- отправка: воркеры через
JavaMailSender, SMS-шлюз, FCM и APNs. Повторы с экспоненциальной задержкой (DefaultErrorHandlerсExponentialBackOffили@RetryableTopicв Spring Kafka), после исчерпания попыток сообщение уходит в DLT; - идемпотентность: доставка at-least-once, поэтому у уведомления есть ключ, и повтор не отправляет его второй раз;
- контроль: rate limit на пользователя и провайдера, статусы доставки в базе, метрики через Micrometer.
Если делали такой сервис, опирайтесь на свои цифры: сообщений в сутки, доля ошибок провайдера, как чинили дубли. Если нет, скажите прямо и разберите решение как дизайн-задачу.
Где спотыкаются
Отправляют письмо прямо в HTTP-запросе или внутри @Transactional. Медленный SMTP держит поток и транзакцию, а сбой провайдера откатывает бизнес-операцию.
Вызывают kafkaTemplate.send() и не смотрят на результат. Метод асинхронный, возвращает CompletableFuture, и без обработки ошибок сообщения теряются молча, а клиент видит «отправлено».
Забывают про дубли и отписки. Повтор без ключа идемпотентности шлёт SMS дважды, а это прямые деньги. Рекламная рассылка без учёта отписки нарушает закон.