StudyCode
Очередь (RabbitMQ, Kafka, SQS) выносит долгую работу из HTTP-обработчика: producer кладёт задачу и мгновенно отвечает клиенту (например, 202 Accepted), consumer — отдельный процесс — обрабатывает её в своём темпе. Это даёт: быстрые ответы (письмо не отправляется внутри запроса регистрации), развязку отказов (SMTP лёг — задачи копятся и обработаются позже, а не роняют регистрацию), сглаживание пиков (очередь — буфер между всплеском трафика и воркерами) и независимое масштабирование (медленную обработку ускоряем добавлением consumer'ов). Плата — асинхронность и дубли: типовая гарантия at-least-once требует идемпотентных consumer'ов, а для «отравленных» сообщений нужны ретраи с backoff и dead letter queue.
// Producer: ответ мгновенный, работа — потом
app.post('/register', async (req, res) => {
const user = await db.users.create(req.body);
await queue.publish('emails', { userId: user.id });
res.status(202).json({ ok: true }); // ~25 мс вместо 3 секунд
});
// Consumer: отдельный процесс, идемпотентный
queue.consume('emails', async (msg) => {
if (await db.processed.exists(msg.id)) return msg.ack(); // дубль
await sendWelcomeEmail(msg.userId);
await db.processed.insert(msg.id);
await msg.ack(); // без ack брокер доставит сообщение снова
});