Builders Academy
Message Queues — Traitement Asynchrone
1 of 2

Chapitre 1 · Leçon 1

BullMQ

Jobs background, retries et priorités

Section 1

Pourquoi des queues ?

Step 1

Découpler le traitement long de la requête HTTP

Certaines opérations sont trop longues pour une requête HTTP synchrone (envoi d'email, génération PDF, redimensionnement d'image). Les queues permettent de répondre immédiatement au client et de traiter en arrière-plan.

snippet.typescript

typescript
1// Sans queue — l'utilisateur attend tout
2app.post("/api/register", async (req, res) => {
3  const user = await createUser(req.body);
4  await sendWelcomeEmail(user.email);      // 2-3 secondes
5  await generateAvatar(user.id);           // 5 secondes
6  await indexUserInSearch(user);           // 1 seconde
7  await notifyAdmins(user);               // 1 seconde
8  // Total : ~9 secondes d'attente ! ❌
9  res.status(201).json({ user });
10});
11
12// ─── Avec BullMQ — réponse immédiate, traitement async ────────
13import { Queue, Worker, Job } from "bullmq";
14import { createClient } from "redis";
15
16const connection = createClient({ url: process.env.REDIS_URL });
17
18// Définir les queues
19export const emailQueue = new Queue("emails", { connection });
20export const mediaQueue  = new Queue("media",  { connection });
21export const searchQueue = new Queue("search", { connection });
22
23// Route — réponse en < 100ms
24app.post("/api/register", async (req, res) => {
25  const user = await createUser(req.body);
26
27  // Ajouter les jobs en queue — non bloquant
28  await emailQueue.add("welcome-email", {
29    userId: user.id,
30    email: user.email,
31    firstName: user.firstName,
32  }, {
33    attempts: 3,                    // 3 tentatives si erreur
34    backoff: { type: "exponential", delay: 1000 }, // 1s, 2s, 4s
35    priority: 1,                    // Haute priorité
36  });
37
38  await mediaQueue.add("generate-avatar", { userId: user.id }, {
39    delay: 2000,                    // Démarrer dans 2 secondes
40    removeOnComplete: { count: 100 }, // Garder 100 jobs complétés
41    removeOnFail: { count: 1000 },
42  });
43
44  res.status(201).json({ user }); // Réponse immédiate ✅
45});

Step 2

Workers — consommer les jobs

Un Worker consomme les jobs d'une queue. Il peut y avoir plusieurs workers en parallèle (concurrence), sur plusieurs machines.

snippet.typescript

typescript
1// Sans queue — l'utilisateur attend tout
2app.post("/api/register", async (req, res) => {
3  const user = await createUser(req.body);
4  await sendWelcomeEmail(user.email);      // 2-3 secondes
5  await generateAvatar(user.id);           // 5 secondes
6  await indexUserInSearch(user);           // 1 seconde
7  await notifyAdmins(user);               // 1 seconde
8  // Total : ~9 secondes d'attente ! ❌
9  res.status(201).json({ user });
10});
11
12// ─── Avec BullMQ — réponse immédiate, traitement async ────────
13import { Queue, Worker, Job } from "bullmq";
14import { createClient } from "redis";
15
16const connection = createClient({ url: process.env.REDIS_URL });
17
18// Définir les queues
19export const emailQueue = new Queue("emails", { connection });
20export const mediaQueue  = new Queue("media",  { connection });
21export const searchQueue = new Queue("search", { connection });
22
23// Route — réponse en < 100ms
24app.post("/api/register", async (req, res) => {
25  const user = await createUser(req.body);
26
27  // Ajouter les jobs en queue — non bloquant
28  await emailQueue.add("welcome-email", {
29    userId: user.id,
30    email: user.email,
31    firstName: user.firstName,
32  }, {
33    attempts: 3,                    // 3 tentatives si erreur
34    backoff: { type: "exponential", delay: 1000 }, // 1s, 2s, 4s
35    priority: 1,                    // Haute priorité
36  });
37
38  await mediaQueue.add("generate-avatar", { userId: user.id }, {
39    delay: 2000,                    // Démarrer dans 2 secondes
40    removeOnComplete: { count: 100 }, // Garder 100 jobs complétés
41    removeOnFail: { count: 1000 },
42  });
43
44  res.status(201).json({ user }); // Réponse immédiate ✅
45});

Topics and skills covered

  • BullMQ
  • Jobs
  • Redis
  • Background Processing
  • Queues