Ответ вслух Senior Кеш и очереди обновлено

Отложенные задачи: напоминание через 24 часа

Вопрос

Нужно отправить пользователю напоминание через 24 часа после регистрации, если он не подтвердил email. Сервис в нескольких репликах. Как сделаете?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Таймер в процессе не подходит: при рестарте он теряется, а в четырёх репликах сработает четыре раза. Нужно надёжное хранилище задач.

Что должно прозвучать в ответе

  • Не `setTimeout`: таймер в памяти теряется при рестарте и дублируется в репликах

  • Вариант 1: отложенная задача в очереди (BullMQ `delay`, отложенные сообщения брокера) с jobId от userId для дедупликации

  • Вариант 2: запись в таблицу с `run_at` и воркер, который выбирает созревшие задачи через `SELECT ... FOR UPDATE SKIP LOCKED`

  • В момент выполнения перепроверяю условие (email всё ещё не подтверждён), потому что за сутки состояние могло измениться

  • Идемпотентность и ретраи: повтор задачи не шлёт второе письмо (отметка об отправке)

  • Мониторинг: отставание очереди, упавшие задачи, DLQ

Что могут спросить следом

  • Почему перепроверять условие в момент выполнения?
  • Как отменить задачу, если пользователь подтвердил email?
  • Что будет при миллионе задач на одну секунду?

Разбор

Таймер в процессе не подходит: при рестарте он теряется, а в четырёх репликах сработает четыре раза. Нужно надёжное хранилище задач. Если в проекте есть Redis, беру BullMQ с delay и jobId, построенным из userId: повторная постановка не создаст дубль, а задачу можно удалить при подтверждении email. Если хочется без лишней инфраструктуры, таблица jobs(run_at, payload, status) и воркер, который раз в несколько секунд забирает созревшие задачи через FOR UPDATE SKIP LOCKED: реплики не мешают друг другу и не берут одно и то же. В момент выполнения обязательно перепроверяю условие, потому что за сутки пользователь мог подтвердить почту. Обработчик идемпотентный, с отметкой об отправке, чтобы ретрай не прислал второе письмо. И мониторю отставание очереди и упавшие задачи.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.