Communication inter-conteneurs avec RabbitMQ et Node.js

Dans les architectures modernes orientées microservices, la communication entre services distribués devient un enjeu majeur. L’une des solutions les plus efficaces repose sur un système de messagerie asynchrone comme RabbitMQ. Cet article présente une démonstration simple d’une application Node.js utilisant RabbitMQ pour échanger des messages entre deux conteneurs Docker.

Objectif

  • Démarrer un conteneur RabbitMQ avec son interface d’administration.
  • Créer une application Node.js productrice de messages.
  • Créer une application Node.js consommatrice de messages.
  • Tester la communication entre les deux via RabbitMQ.

Architecture du projet

+---------------+         +------------------+         +----------------+
| Producer | ----> | RabbitMQ | ----> | Consumer |
+---------------+ +------------------+ +----------------+
| | |
| Docker Compose | Réseau Docker |

Contenu du fichier docker-compose.yml

version: '3.8'

services:
rabbitmq:
image: rabbitmq:3-management
ports:
- "15672:15672"
- "5672:5672"
networks:
- rabbitmq-net
environment:
- RABBITMQ_DEFAULT_USER=guest
- RABBITMQ_DEFAULT_PASS=guest
privileged: true
mem_limit: 256m
restart: always

node-app:
build:
context: ./node-app
container_name: node-app
networks:
- rabbitmq-net
environment:
- RABBITMQ_URL=amqp://guest:guest@rabbitmq:5672
depends_on:
- rabbitmq
restart: always

node-consumer:
build:
context: ./node-consumer
container_name: node-consumer
networks:
- rabbitmq-net
environment:
- RABBITMQ_URL=amqp://guest:guest@rabbitmq:5672
depends_on:
- rabbitmq
restart: always

networks:
rabbitmq-net:
driver: bridge

Structure des dossiers

project-root/
├── docker-compose.yml
├── node-app/
│ └── app.js
│ └── package.json
├── node-consumer/
└── consumer.js
└── package.json

Contenu de node-app/app.js (Producer)

const amqp = require('amqplib');

const sendMessage = async () => {
const queue = 'tasks';
const message = 'Hello from producer!';

try {
const connection = await amqp.connect(process.env.RABBITMQ_URL);
const channel = await connection.createChannel();

await channel.assertQueue(queue, { durable: true });
channel.sendToQueue(queue, Buffer.from(message));

console.log(`Message sent: ${message}`);
setTimeout(() => {
connection.close();
}, 500);
} catch (err) {
console.error('Error:', err);
}
};

sendMessage();

Contenu de node-consumer/consumer.js

const amqp = require('amqplib');

const receiveMessage = async () => {
const queue = 'tasks';

try {
const connection = await amqp.connect(process.env.RABBITMQ_URL);
const channel = await connection.createChannel();

await channel.assertQueue(queue, { durable: true });

console.log(`Waiting for messages in queue: ${queue}`);
channel.consume(queue, (msg) => {
if (msg !== null) {
console.log(`Received message: ${msg.content.toString()}`);
channel.ack(msg);
}
});
} catch (err) {
console.error('Error:', err);
}
};

receiveMessage();

Lancer le projet

Dans le terminal, à la racine du projet :

docker-compose up --build

Ensuite :

  • Accédez à http://localhost:15672 pour l’interface de RabbitMQ.
  • Connectez-vous avec guest / guest.
  • Vous pouvez y visualiser la file « tasks », les messages et les connexions.

Résultat attendu

  • Le producer envoie un message dans la queue.
  • Le consumer reçoit le message et l’affiche dans la console.

Conclusion

Ce mini-projet permet de découvrir concrètement comment RabbitMQ peut servir d’intermédiaire entre deux applications Node.js conteneurisées. Une base idéale pour explorer des architectures orientées messages dans des systèmes distribués !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *