0Pricing
PHP Academy · Leçon

Travailler avec RabbitMQ en PHP

Publiez et consommez des messages avec RabbitMQ.

Travailler avec RabbitMQ en PHP est une leçon PHP Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage PHP Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours PHP Academy comprend 4 leçons au total.

RabbitMQ en PHP

RabbitMQ est un courtier qui utilise AMQP 0-9-1. En PHP, le client de référence est php-amqplib/php-amqplib (en PHP pur) ou ext-amqp, qui s'appuie sur le langage C. Cette leçon utilise php-amqplib, car il fonctionne partout où Composer fonctionne.

Le modèle AMQP de base comporte trois acteurs : les échanges reçoivent les messages, les liaisons les acheminent à l'aide d'une clé et les files d'attente les conservent pour les consommateurs. Maîtrisez ce modèle, et le reste ne sera qu'un détail.

Installation du client

Ajoutez la bibliothèque avec Composer. Elle nécessite les extensions sockets et bcmath, toutes deux courantes dans les versions CLI de PHP.

composer require php-amqplib/php-amqplib
# Connection target, e.g. amqp://guest:guest@localhost:5672/

Le modèle échanges/files d'attente/liaisons

Les producteurs publient leurs messages dans un échange, jamais directement dans une file d'attente. Le type d'échange détermine le routage :

  • direct — correspondance exacte avec la clé de routage.
  • topic — motifs avec caractères génériques, comme order.*.eu.
  • fanout — diffusion à toutes les files d'attente liées.
  • headers — correspondance selon les attributs des en-têtes.

Une liaison relie une file d'attente à un échange au moyen d'un motif de routage. Découpler les producteurs de la topologie des files d'attente est tout l'intérêt de la couche d'échange.

Connexion et déclaration

Ouvrez une connexion, obtenez un canal et déclarez votre topologie. durable: true permet à l’échange et à la file d’attente de survivre au redémarrage du courtier. Les déclarations sont idempotentes : déclarer une entité existante avec des arguments correspondants ne produit aucun effet.

<?php
require 'vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;

$conn = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$ch = $conn->channel();

$ch->exchange_declare('orders', 'topic', false, true, false);
$ch->queue_declare('orders.email', false, true, false, false);
$ch->queue_bind('orders.email', 'orders', 'order.created');

echo "Topology ready\n";
$ch->close();
$conn->close();

Publication d’un message

Enveloppez le corps dans un AMQPMessage. Définissez delivery_mode = 2 pour rendre le message persistant — c’est la combinaison d’une file durable et d’un message persistant qui survit à un redémarrage ; l’un sans l’autre ne suffit pas.

<?php
require 'vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

$conn = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$ch = $conn->channel();

$payload = json_encode(['orderId' => 42, 'total' => 19.90]);
$msg = new AMQPMessage($payload, [
    'content_type'  => 'application/json',
    'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT,
    'message_id'    => bin2hex(random_bytes(8)),
]);

$ch->basic_publish($msg, 'orders', 'order.created');
echo "Published\n";
$ch->close();
$conn->close();

Consommation avec accusé manuel

Enregistrez un rappel avec basic_consume. Passez no_ack = false afin de contrôler l’accusé de réception. N’envoyez l’accusé qu’une fois le traitement réussi ; en cas d’échec, basic_nack avec remise en file permet à RabbitMQ de livrer à nouveau le message.

<?php
require 'vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;

$conn = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$ch = $conn->channel();
$ch->basic_qos(null, 10, null); // prefetch 10

$callback = function ($msg) {
    $data = json_decode($msg->getBody(), true);
    try {
        // ... do work ...
        $msg->ack();
    } catch (\Throwable $e) {
        $msg->nack(true); // requeue
    }
};

$ch->basic_consume('orders.email', '', false, false, false, false, $callback);
while ($ch->is_consuming()) {
    $ch->wait();
}

Prélecture et distribution équitable

Par défaut, RabbitMQ distribue les messages à tour de rôle aux consommateurs, sans tenir compte de leur charge respective — un consommateur lent accumule donc du travail. basic_qos(null, prefetch, null) limite le nombre de messages non acquittés qu’un consommateur peut détenir.

Définissez la prélecture sur une petite valeur (par ex. 1–10) pour les tâches lourdes et inégales, afin que le courtier n’envoie du nouveau travail qu’aux consommateurs disposant de capacité libre. C’est la distribution équitable.

Confirmations du producteur

basic_publish renvoie immédiatement et ne vous indique pas si le courtier a accepté le message. Pour garantir la publication, activez les confirmations du producteur : le courtier envoie un accusé dès que le message est correctement conservé ou acheminé.

<?php
require 'vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

$conn = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$ch = $conn->channel();
$ch->confirm_select(); // enable confirms on this channel

$ch->set_ack_handler(fn($m) => print("confirmed\n"));
$ch->set_nack_handler(fn($m) => print("REJECTED\n"));

$ch->basic_publish(new AMQPMessage('hi'), 'orders', 'order.created');
$ch->wait_for_pending_acks(5.0); // block until confirmed or timeout

Mise en file des messages rejetés

Configurez l’argument x-dead-letter-exchange d’une file afin que les messages rejetés (nack sans remise en file) ou expirés soient acheminés vers un DLX. Combinez-le avec x-delivery-limit sur les files de quorum afin de plafonner automatiquement les tentatives.

<?php
use PhpAmqpLib\Wire\AMQPTable;

$args = new AMQPTable([
    'x-dead-letter-exchange'    => 'orders.dlx',
    'x-dead-letter-routing-key' => 'order.failed',
    'x-message-ttl'             => 60000, // ms before expiry
]);
// false=passive, true=durable, false=exclusive, false=autodelete, args
$ch->queue_declare('orders.email', false, true, false, false, false, $args);
$ch->queue_declare('orders.dead', false, true, false, false);
$ch->queue_bind('orders.dead', 'orders.dlx', 'order.failed');

Exécution des processus de traitement en production

Voici quelques règles opérationnelles essentielles pour les processus de traitement PHP utilisant RabbitMQ :

  • Exécutez les consommateurs comme des processus CLI de longue durée sous la supervision d’un superviseur (systemd / Supervisor) qui les redémarre à leur arrêt.
  • PHP accumule des fuites mémoire au fil du temps — redémarrez le processus après N messages ou lorsqu’un seuil de mémoire est atteint.
  • Envoyez des signaux de maintien de connexion AMQP et gérez SIGTERM pour permettre un arrêt progressif (terminez le message en cours, puis arrêtez-vous).
  • Utilisez des files de quorum pour la haute disponibilité (HA) plutôt que les anciennes files miroir.

Arrêt progressif

Les déploiements envoient SIGTERM. Un processus de traitement naïf s’arrête au milieu d’un message, ce qui force une nouvelle livraison. Installez un gestionnaire de signal qui inverse un indicateur ; terminez le message actuel, acquittez-le, puis sortez proprement de la boucle de consommation. pcntl_async_signals(true) permet à PHP de transmettre le signal entre deux attentes AMQP.

<?php
pcntl_async_signals(true);
$running = true;
pcntl_signal(SIGTERM, function () use (&$running) {
    $running = false; // stop after the current message
    echo "SIGTERM: draining...\n";
});

while ($running && $ch->is_consuming()) {
    try {
        $ch->wait(null, false, 5); // wakes for signals
    } catch (\PhpAmqpLib\Exception\AMQPTimeoutException $e) {
        // idle tick - loop and re-check $running
    }
}
$ch->close();
echo "Stopped cleanly\n";

Vérification rapide

Survivre au redémarrage d’un courtier.

Récapitulatif

Vous pouvez maintenant construire un véritable flux de traitement RabbitMQ en PHP :

  • Publiez dans un échange ; acheminez les messages via des liaisons vers des files.
  • La combinaison file durable + message persistant survit aux redémarrages.
  • Consommez avec un accusé manuel et ajustez basic_qos prélecture pour une distribution équitable.
  • Utilisez les confirmations du producteur pour garantir les envois et un DLX pour les messages irrécupérables.
  • Exécutez les processus de traitement sous la supervision d’un superviseur, avec des signaux de maintien de connexion et un arrêt progressif.

Ensuite : Kafka, lorsque vous avez besoin de flux de données à haut débit plutôt que de mise en file de tâches.

Questions Fréquemment Posées

La leçon « Travailler avec RabbitMQ en PHP » est-elle gratuite ?

Oui — le texte complet de « Travailler avec RabbitMQ en PHP » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours PHP Academy, passe à CoddyKit PRO. Le cours PHP Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Travailler avec RabbitMQ en PHP » ?

Publiez et consommez des messages avec RabbitMQ. Tu pratiques PHP Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer PHP Academy ?

Aucune expérience préalable n'est requise. PHP Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Travailler avec RabbitMQ en PHP » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon PHP Academy ?

Oui. Chaque leçon PHP Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Pourquoi la messagerie asynchrone
  2. Travailler avec RabbitMQ en PHP
  3. Apache Kafka avec PHP
  4. Créer des flux de travail orientés événements
← Retour à PHP Academy