Arbeta med RabbitMQ i PHP
Publicera och konsumera meddelanden med RabbitMQ.
Arbeta med RabbitMQ i PHP är en gratis lektion i PHP Academy på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för PHP Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i PHP Academy innehåller totalt 4 lektioner.
RabbitMQ i PHP
RabbitMQ är en broker som talar AMQP 0-9-1. I PHP är den etablerade klienten php-amqplib/php-amqplib (ren PHP) eller det C-baserade ext-amqp. Den här lektionen använder php-amqplib eftersom det körs överallt där Composer körs.
Den centrala AMQP-modellen har tre aktörer: exchanges tar emot meddelanden, bindings routar dem efter nyckel och queues håller dem åt konsumenterna. Bemästra detta, så är resten detaljer.
Installera klienten
Lägg till biblioteket med Composer. Det kräver tilläggen sockets och bcmath, som båda är vanliga i CLI-byggen av PHP.
composer require php-amqplib/php-amqplib
# Connection target, e.g. amqp://guest:guest@localhost:5672/Modellen med exchange, queue och binding
Producenter publicerar till en exchange, aldrig direkt till en queue. Exchange-typen avgör routningen:
direct— exakt matchning av routing-nyckeln.topic— jokerteckenmönster somorder.*.eu.fanout— sändning till alla bundna köer.headers— matchning baserad på attribut i headers.
En binding kopplar en queue till en exchange med ett routingmönster. Att frikoppla producenter från kötopologin är hela poängen med exchange-lagret.
Ansluta och deklarera
Öppna en anslutning, hämta en kanal och deklarera topologin. durable: true gör att både exchange och kö överlever en omstart av brokern. Deklarationer är idempotenta — att deklarera en befintlig entitet med matchande argument är en no-op.
<?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();Publicera ett meddelande
Lägg innehållet i ett AMQPMessage. Ange delivery_mode = 2 för att göra meddelandet persistent — det är kombinationen av en durable kö och ett persistent meddelande som överlever en omstart (det ena utan det andra gör det inte).
<?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();Konsumera med manuell ack
Registrera en callback med basic_consume. Ange no_ack = false så att ni själva styr ackningen. Skicka ack först när arbetet har lyckats; vid fel kan basic_nack med requeue låta RabbitMQ leverera meddelandet igen.
<?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();
}Prefetch och rättvis distribution
Som standard fördelar RabbitMQ meddelanden enligt round-robin, utan hänsyn till hur upptagen varje konsument är — en långsam konsument samlar på sig arbete. basic_qos(null, prefetch, null) begränsar antalet obekräftade meddelanden som en konsument får hålla.
Ange prefetch till ett litet tal (t.ex. 1–10) för tunga och ojämnt fördelade uppgifter, så att brokern bara skickar nytt arbete till konsumenter som har ledig kapacitet. Detta är rättvis distribution.
Publisher confirms
basic_publish returnerar omedelbart och talar inte om för er om brokern accepterade meddelandet. För garanterad publicering aktiverar ni publisher confirms: brokern skickar en ack när meddelandet har sparats eller dirigerats på ett säkert sätt.
<?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 timeoutDead lettering
Konfigurera argumentet x-dead-letter-exchange för en kö, så att avvisade meddelanden (nack utan requeue) eller utgångna meddelanden dirigeras till en DLX. Kombinera detta med x-delivery-limit för quorum queues, så begränsas antalet försök automatiskt.
<?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');Köra workers i produktion
Några praktiska driftsregler för PHP-workers med RabbitMQ:
- Kör konsumenter som långlivade CLI-processer under en supervisor (systemd / Supervisor) som startar om dem när de avslutas.
- PHP läcker minne över tid — starta om workern efter N meddelanden eller när en minnesgräns nås.
- Skicka AMQP-heartbeats och hantera
SIGTERMför en graciös avstängning (slutför meddelandet som behandlas och stoppa sedan). - Använd quorum queues för HA i stället för äldre speglade köer.
Graciös avstängning
Distributioner skickar SIGTERM. En naiv worker avslutas mitt i ett meddelande, vilket tvingar fram en ny leverans. Installera en signalhanterare som sätter en flagga; slutför det aktuella meddelandet, skicka ack och avsluta sedan consume-loopen på ett ordnat sätt. pcntl_async_signals(true) gör att PHP kan leverera signalen mellan väntan på AMQP-operationer.
<?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";Snabb kontroll
Överleva en omstart av brokern.
Sammanfattning
Ni kan nu bygga en riktig RabbitMQ-pipeline i PHP:
- Publicera till en exchange; dirigera via bindings till köer.
- En durable kö + ett persistent meddelande överlever omstarter.
- Konsumera med manuell ack och finjustera basic_qos prefetch för rättvis distribution.
- Använd publisher confirms för garanterade publiceringar och en DLX för meddelanden som inte kan behandlas.
- Kör workers under en supervisor med heartbeats och graciös avstängning.
Nästa steg: Kafka, när ni behöver höggenomströmningsströmning i stället för uppgiftsköer.
Lär dig PHP med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 49
- Lektioner
- 195
Vanliga frågor
Är lektionen ”Arbeta med RabbitMQ i PHP” gratis?
Ja – hela texten till ”Arbeta med RabbitMQ i PHP” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i PHP Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i PHP Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Arbeta med RabbitMQ i PHP”?
Publicera och konsumera meddelanden med RabbitMQ. Ni övar på PHP Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig PHP Academy?
Du behöver inga förkunskaper. Utbildningen i PHP Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”Arbeta med RabbitMQ i PHP”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här PHP Academy-lektionen?
Ja. Varje PHP Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Varför asynkron meddelandehantering
- Arbeta med RabbitMQ i PHP
- Apache Kafka med PHP
- Bygga händelsestyrda arbetsflöden