RabbitMQ
Un broker de messages éprouvé : tes services déposent des messages dans des files, d'autres viennent les consommer, avec acquittement et redistribution automatique. La poste fiable du monde du backend.
Les deux acheminent des messages, mais le modèle diffère. RabbitMQ = file d'attente : un message consommé est enlevé de la file, idéal pour distribuer des tâches entre workers (« qui prend celui-là ? »). Kafka = journal persistant : les messages restent et peuvent être rejoués par plusieurs consommateurs indépendants. Pour un projet Python qui veut décharger des tâches asynchrones avec Celery, RabbitMQ ou Redis sont les choix naturels.
À quoi ça sert
Ton API reçoit une requête qui demande de générer un PDF, d'envoyer un
e-mail, ou de lancer une prédiction lourde. Tu ne veux pas que
l'utilisateur attende la fin du travail. Solution : tu déposes un
« ticket » dans une file, ton API répond
{"status":"queued"}, et un worker en arrière-plan
prend les tickets un par un et les traite.
RabbitMQ est ce qui s'occupe de la file. Trois concepts à retenir :
- Queue — la file d'attente. Les messages s'accumulent ici en attendant d'être consommés.
- Exchange — l'aiguilleur. Les producteurs publient toujours sur un exchange, qui décide vers quelle(s) queue(s) router le message selon des règles (clé de routage, type d'exchange).
- Binding — la règle qui relie un exchange à une queue.
Le tout avec acquittement : un message n'est retiré que si le worker confirme qu'il l'a traité. Si le worker crashe avant de confirmer, RabbitMQ redonne le message à un autre worker. Tu ne perds rien.
RabbitMQ = la poste fiable qui prend tes messages, les range dans la bonne boîte, et garantit qu'ils seront livrés à un destinataire — quitte à réessayer.
Un exemple d'usage
Une route FastAPI déclenche l'envoi d'un e-mail de bienvenue. On veut que l'API rende la main tout de suite et qu'un worker à part s'occupe de parler au serveur SMTP (qui est lent et peut planter).
import pika, json
connection = pika.BlockingConnection(pika.ConnectionParameters("localhost"))
channel = connection.channel()
channel.queue_declare(queue="emails", durable=True)
channel.basic_publish(
exchange="",
routing_key="emails",
body=json.dumps({"to": "a@b.fr", "subject": "Bienvenue"}),
properties=pika.BasicProperties(delivery_mode=2), # persistant
)
import pika, json
connection = pika.BlockingConnection(pika.ConnectionParameters("localhost"))
channel = connection.channel()
channel.queue_declare(queue="emails", durable=True)
channel.basic_qos(prefetch_count=1)
def handle(ch, method, props, body):
job = json.loads(body)
send_email(job["to"], job["subject"])
ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_consume(queue="emails", on_message_callback=handle)
channel.start_consuming()
Lance plusieurs workers : RabbitMQ distribue les messages en round-robin, débit ×N. En vrai, pour faire ça en Python on n'écrit presque jamais ce code à la main : on utilise Celery, qui s'occupe de tout.
How-to : démarrer avec RabbitMQ
-
Lancer RabbitMQ avec Docker
L'image officielle existe avec UI de management intégrée — c'est celle-là qu'on utilise pour apprendre :
bashdocker run -d --name rabbitmq \ -p 5672:5672 -p 15672:15672 \ -v rabbitmq-data:/var/lib/rabbitmq \ rabbitmq:3-management5672: port AMQP, utilisé par tes apps.15672: UI web. Login par défaut :guest/guest.
-
Découvrir l'UI de management
http://localhost:15672. Onglets clés :- Queues — liste des files, taux de messages/s entrants et sortants, profondeur (combien attendent).
- Exchanges — les aiguilleurs. Tu en as déjà
quelques-uns par défaut (
amq.direct,amq.fanout…). - Connections et Channels — qui parle au broker en ce moment.
Tu peux publier un message à la main depuis l'UI — pratique pour tester un worker sans écrire un producer.
-
Installer le client Python
bashuv add pikapikaest synchrone et simple à lire. Pour de l'async, regardeaio-pika. -
Comprendre les types d'exchanges
- direct — route selon une routing key
exacte.
orders.createdarrive dans la queue bindée surorders.created. - fanout — diffuse à toutes les queues bindées (broadcast). Utile pour notifier plusieurs services simultanément.
- topic — comme direct mais avec wildcards :
orders.*attrapeorders.createdetorders.cancelled. - headers — route selon les en-têtes du message. Plus rare.
Pour démarrer, l'exchange par défaut (vide) suffit : il route vers la queue dont le nom = la routing key. C'est ce qu'on voit dans l'exemple plus haut.
- direct — route selon une routing key
exacte.
-
Acks et durabilité
Trois choses à activer ensemble pour ne rien perdre :
- Queue durable :
queue_declare(queue=..., durable=True). - Message persistant :
delivery_mode=2dans les properties. - Ack manuel : le worker appelle
basic_ackseulement après avoir réussi le travail. Si le worker crashe avant, RabbitMQ redélivre.
basic_qos(prefetch_count=1)dit au broker de ne pas envoyer plus d'un message non-acké à la fois à ce worker — sinon un worker rapide accapare la file. - Queue durable :
-
Dead letter queue (DLQ)
Pour les messages qui échouent en boucle (poison pills), configure la queue avec une dead-letter-exchange : après n tentatives ratées, le message est routé vers une file de quarantaine. Tu vas la voir et décider quoi en faire, plutôt que tourner en rond.
Aide-mémoire
rabbitmqctl list_queues name messages consumers
rabbitmqctl list_exchanges name type
rabbitmqctl list_bindings
rabbitmqctl add_user app monsecret
rabbitmqctl set_permissions -p / app ".*" ".*" ".*"
# Format AMQP standard, accepté par pika, Celery, etc.
amqp://user:password@host:5672/vhost
# En local par défaut
amqp://guest:guest@localhost:5672/
RabbitMQ et le reste de l'écosystème
- Celery — l'usage n°1 de RabbitMQ en Python. Tu écris des fonctions, Celery gère la sérialisation, les retries, les acks. Redis est l'autre broker possible (plus simple, moins de garanties).
- Kafka — voir l'encart en haut : modèles différents, choisis selon ton besoin.
- FastAPI — pattern classique : route → publication d'une tâche → réponse 202 Accepted. Le travail lourd se fait ailleurs.
-
Docker — l'image
rabbitmq:3-managementest l'installation type. Sur Kubernetes, l'opérateur officiel gère cluster, persistence et upgrades. -
Prometheus +
Grafana — RabbitMQ expose un
endpoint
/metricsPrometheus depuis sa version 3.8 (via plugin). Dashboard tout prêt sur grafana.com (id 10991).
Pour aller plus loin
- Documentation officielle : rabbitmq.com/documentation
- Tutoriels pas à pas : rabbitmq.com/tutorials (Hello World jusqu'au RPC)
- Client Python pika : pika.readthedocs.io