Introduction : pourquoi votre serveur dort quand il devrait travailler
\n\nImaginez : un utilisateur clique sur le bouton « Envoyer le rapport », et la page se fige pendant 30 secondes. Le serveur génère un PDF, compresse des images et envoie un e-mail — tout cela de manière synchrone. Ça vous dit quelque chose ? Si oui, vous êtes tombé dans le piège du code bloquant.
\n\nDans cet article, nous allons voir comment les files d'attente et les tâches en arrière-plan avec TypeScript résolvent ce problème. Vous apprendrez à déplacer les tâches lourdes vers des processus en arrière-plan, sans perdre le contrôle sur les erreurs et la scalabilité. Ce contenu est conçu pour les développeurs qui connaissent déjà Node.js et souhaitent faire passer leur projet au niveau supérieur.
\n\nNous aborderons les bibliothèques Bull et BullMQ, nous parlerons de RabbitMQ et nous montrerons des exemples de code concrets en TypeScript. C'est parti !
Qu'est-ce qu'une file d'attente de tâches et pourquoi en avez-vous besoin
\n\nUne file d'attente de tâches (task queue) est un mécanisme qui sépare la requête utilisateur de son exécution. Au lieu de traiter l'opération directement dans le gestionnaire HTTP, nous envoyons la tâche dans une file d'attente, et un worker en arrière-plan la récupère et l'exécute de manière asynchrone.
\n\nCas d'utilisation typiques
\n- \n
- Envoi d'e-mails et de notifications push \n
- Génération de PDF, d'images, de vidéos \n
- Parsing de données et web scraping \n
- Traitement des commandes dans les boutiques en ligne
- Calculs et rapports volumineux
Sans files d'attente, votre application risque de planter sous la charge. Avec elles, vous gagnez en tolérance aux pannes (si un worker tombe, la tâche n'est pas perdue) et en scalabilité (vous pouvez lancer 10 workers au lieu d'un seul).
\n\nBull et BullMQ : des files d'attente puissantes pour Node.js
\n\nBull est la bibliothèque la plus populaire pour travailler avec les files d'attente dans l'écosystème Node.js. Elle est basée sur Redis et prend en charge TypeScript nativement. BullMQ est son successeur, plus moderne, avec le support des sandbox (processus isolés) et une gestion avancée.
\n\nInstallation et configuration de base
\nnpm install bullmq ioredis\nnpm install -D @types/bull\n\nCréons une file d'attente et un worker en TypeScript :
\n\n// queue.ts\nimport { Queue } from 'bullmq';\n\nconst connection = {\n host: 'localhost',\n port: 6379,\n};\n\nexport const emailQueue = new Queue('email', { connection });\n\n// worker.ts\nimport { Worker } from 'bullmq';\nimport { sendEmail } from './emailService';\n\nconst worker = new Worker('email', async job => {\n const { to, subject, body } = job.data;\n await sendEmail(to, subject, body);\n console.log(`E-mail envoyé à ${to}`);\n}, { connection });\n\nworker.on('completed', job => {\n console.log(`Tâche ${job.id} terminée`);\n});\n\nworker.on('failed', (job, err) => {\n console.error(`Tâche ${job.id} échouée : ${err.message}`);\n});\n\nMaintenant, à n'importe quel endroit de l'application, nous pouvons ajouter une tâche :
\n\nimport { emailQueue } from './queue';\n\nawait emailQueue.add('send-welcome', {\n to: 'user@example.com',\n subject: 'Bienvenue !',\n body: 'Merci de vous être inscrit...'\n});\n\nSimple, non ? Mais ce n'est que le début. BullMQ offre bien plus de possibilités.
\n\nFonctionnalités avancées de BullMQ
\n- \n
- Tentatives répétées — si une tâche échoue, elle peut être automatiquement relancée après N secondes. \n
- Exécution différée — planifier une tâche pour une heure précise. \n
- Priorités — les tâches urgentes sont traitées en premier. \n
- Événements — vous pouvez vous abonner à la progression, à la fin, aux erreurs. \n
- Sandbox — exécution du code dans un processus isolé (sécurité + propreté). \n
Exemple avec tentatives et délai :
\n\nawait emailQueue.add('send-invoice', {\n invoiceId: 123,\n email: 'client@example.com'\n}, {\n attempts: 5,\n backoff: { type: 'expon