Tryb routingu RabbitMQ (Tryb bezpośredni)
W trybie routingu RabbitMQ używany jest typ wymiany "direct". Główną różnicą w porównaniu do trybu publikacji-subskrypcji jest to, że wymiana bezpośrednia dostarcza wiadomości do kolejek, których parametry routingu są całkowicie zgodne. Architektura jest przedstawiona na poniższym schemacie:
Uwaga: Niezależnie od trybu pracy używanego w RabbitMQ, różnica polega na rodzaju wymiany używanej i parametrach routingu.
1. Samouczek wstępny
Proszę najpierw przeczytać następujące sekcje, aby zrozumieć odpowiednią wiedzę:
- Podstawowe pojęcia RabbitMQ
- Zasady trybu routingu RabbitMQ
- Szybki start dla PHP z RabbitMQ (wymagane, ponieważ kolejne sekcje nie będą powtarzać kodu, a jedynie wyświetlać kluczowy kod)
- Sekcja Publikuj-Subskrybuj dla PHP w RabbitMQ (wymagane, ponieważ struktura kodu jest prawie taka sama, z wyjątkiem typu wymiany i parametrów routingu)
2. Definiowanie wymiany bezpośredniej
// Deklaruj wymianę
$channel->exchange_declare(
'tizi365.direct', // Unikalna nazwa wymiany
'direct', // Typ wymiany
false,
false, // Czy ma być trwała
false
);
Uwaga: Zarówno producenci, jak i konsumenci wiadomości muszą posiadać wymianę.
3. Wysyłanie wiadomości
Wysyłamy wiadomości do wymiany, a wymiana dostarcza je do odpowiedniej kolejki na podstawie reguł routingu.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
// Tworzenie połączenia RabbitMQ
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
// Tworzenie kanału
$channel = $connection->channel();
// Deklaruj wymianę
$channel->exchange_declare(
'tizi365.direct', // Unikalna nazwa wymiany
'direct', // Typ wymiany
false,
false, // Czy ma być trwała
false
);
// Obiekt wiadomości, treść wiadomości jest parametrem
$msg = new AMQPMessage("witaj tizi365.com");
// Zwróć uwagę na trzeci parametr, parametr routingu
$channel->basic_publish(
$msg, // Obiekt wiadomości
'tizi365.direct', // Nazwa wymiany
"tizi365" // Parametr routingu, może być dowolnie zdefiniowany w zależności od potrzeb
);
echo ' [x] Wysłano ', $msg->getBody(), "\n";
// Zwolnij zasoby
$channel->close();
$connection->close();
Uwaga: Trzeci parametr w metodzie
basic_publish
jest kluczowym parametrem.
4. Odbieranie wiadomości
4.1. Zdefiniuj kolejkę i powiąż wymianę
Aby konsumować wiadomości z kolejki, musisz najpierw zdefiniować kolejkę, a następnie powiązać ją z docelową wymianą.
// Zadeklaruj anonimową kolejkę
list($nazwa_kolejki, ,) = $channel->queue_declare("", false, false, true, false);
// Powiąż kolejkę z określoną wymianą
$channel->queue_bind(
$nazwa_kolejki, // Nazwa kolejki
'tizi365.fanout', // Nazwa wymiany
"tizi365" // Parametr powiązania trasowania, powiąż tutaj z 'tizi365'
);
Uwaga: Zgodnie z zasadami wymiany bezpośredniej, jeśli parametr trasowania przekazywany podczas wysyłania wiadomości pasuje do parametru trasowania ustawionego podczas powiązania kolejki z wymianą, wiadomość zostanie dostarczona do tej kolejki.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
// Utwórz połączenie rabbitmq
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
// Utwórz kanał
$channel = $connection->channel();
// Zadeklaruj wymianę
$channel->exchange_declare(
'tizi365.direct', // Nazwa wymiany, musi być unikalna i nie może się powtarzać
'direct', // Typ wymiany
false,
false, // Czy jest trwała
false
);
// Zadeklaruj anonimową kolejkę
list($nazwa_kolejki, ,) = $channel->queue_declare("", false, false, true, false);
// Powiąż kolejkę z określoną wymianą
$channel->queue_bind(
$nazwa_kolejki, // Nazwa kolejki
'tizi365.fanout', // Nazwa wymiany
"tizi365" // Parametr powiązania trasowania, powiąż z 'tizi365' tutaj
);
echo " [*] Oczekiwanie na wiadomość. Aby zakończyć, naciśnij CTRL+C\n";
// Zdefiniuj funkcję obsługi wiadomości (tutaj używamy funkcji anonimowej)
$callback = function ($msg) {
// Logika obsługi wiadomości
echo ' [x] ', $msg->body, "\n";
};
// Utwórz konsumenta
$channel->basic_consume(
$nazwa_kolejki, // Nazwa kolejki, nazwa kolejki do konsumpcji
'', // Etykieta konsumenta, ignorowana, unikalny identyfikator jest generowany automatycznie
false,
true, // Czy automatycznie potwierdzać wiadomość, czyli automatycznie informować rabbitmq, że wiadomość została pomyślnie przetworzona
false,
false,
$callback // Funkcja obsługi wiadomości
);
// Zablokuj proces do momentu, gdy kanał nie zostanie zamknięty, aby zapobiec zakończeniu procesu
while ($channel->is_open()) {
$channel->wait();
}
// Zwolnij zasoby
$channel->close();
$connection->close();