Modo de Roteamento do RabbitMQ com PHP (Modo Direto)
No modo de roteamento do RabbitMQ, o tipo de exchange usado é "direct". A principal diferença do modo publicar-assinar é que a exchange direta entrega mensagens para filas cujos parâmetros de roteamento coincidem completamente. A arquitetura é mostrada no seguinte gráfico:
Observação: Independentemente do modo de trabalho usado no RabbitMQ, a diferença está no tipo de exchange utilizado e nos parâmetros de roteamento.
1. Tutorial Preparatório
Por favor, leia as seguintes seções primeiro para entender o conhecimento relevante:
- Conceitos Básicos do RabbitMQ
- Princípios do Modo de Roteamento do RabbitMQ
- Início Rápido para PHP com RabbitMQ (necessário, pois as seções subsequentes não repetirão o código, apenas mostrarão o código-chave)
- Seção Padrão de Publicar-Assinar do PHP RabbitMQ (necessário, pois a estrutura do código é quase a mesma, exceto pelo tipo de exchange e os parâmetros de roteamento)
2. Definir Exchange Direta
// Declarar a exchange
$channel->exchange_declare(
'tizi365.direct', // Nome único da exchange
'direct', // Tipo de exchange
false,
false, // Se persistir
false
);
Observação: Tanto os produtores quanto os consumidores de mensagens precisam de uma exchange.
3. Enviando Mensagens
Enviamos mensagens para a exchange, e a exchange entrega mensagens para a fila correspondente com base nas regras de roteamento.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
// Criar uma conexão RabbitMQ
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
// Criar um canal
$channel = $connection->channel();
// Declarar a exchange
$channel->exchange_declare(
'tizi365.direct', // Nome único da exchange
'direct', // Tipo de exchange
false,
false, // Se persistir
false
);
// Objeto de mensagem, conteúdo da mensagem é o parâmetro
$msg = new AMQPMessage("olá tizi365.com");
// Preste atenção ao terceiro parâmetro, parâmetro de roteamento
$channel->basic_publish(
$msg, // Objeto de mensagem
'tizi365.direct', // Nome da exchange
"tizi365" // Parâmetro de roteamento, pode ser arbitrariamente definido conforme necessário
);
echo ' [x] Enviado ', $msg->getBody(), "\n";
// Liberar recursos
$channel->close();
$connection->close();
Observação: O terceiro parâmetro no método
basic_publish
é um parâmetro chave.
4. Recebendo Mensagens
4.1. Definir Fila & Vincular Exchange
Para consumir mensagens da fila, você precisa primeiro definir uma fila e depois vinculá-la à exchange de destino.
// Declarar uma fila anônima
list($queue_name, ,) = $channel->queue_declare("", false, false, true, false);
// Vincular a fila à exchange especificada
$channel->queue_bind(
$queue_name, // Nome da fila
'tizi365.fanout', // Nome da exchange
"tizi365" // Parâmetro de roteamento de vinculação, vincular 'tizi365' aqui
);
Nota: De acordo com as regras da exchange direta, se o parâmetro de roteamento enviado ao enviar uma mensagem corresponder ao parâmetro de roteamento definido ao vincular a fila à exchange, a mensagem será entregue a esta fila.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
// Criar uma conexão com o rabbitmq
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
// Criar um Canal
$channel = $connection->channel();
// Declarar uma exchange
$channel->exchange_declare(
'tizi365.direct', // Nome da exchange, deve ser único e não pode ser repetido
'direct', // Tipo de exchange
false,
false, // Se é durável
false
);
// Declarar uma fila anônima
list($queue_name, ,) = $channel->queue_declare("", false, false, true, false);
// Vincular a fila a uma exchange específica
$channel->queue_bind(
$queue_name, // Nome da fila
'tizi365.fanout', // Nome da exchange
"tizi365" // Parâmetro de roteamento de vinculação, vincular 'tizi365' aqui
);
echo " [*] Aguardando mensagem. Pressione CTRL+C para sair\n";
// Definir a função de tratamento de mensagem (usando uma função anônima aqui)
$callback = function ($msg) {
// Lógica de tratamento da mensagem
echo ' [x] ', $msg->body, "\n";
};
// Criar um consumidor
$channel->basic_consume(
$queue_name, // Nome da fila, o nome da fila a ser consumida
'', // Tag do consumidor, ignorado, um ID único é gerado automaticamente
false,
true, // Se deve reconhecer automaticamente a mensagem, ou seja, informar automaticamente ao rabbitmq que a mensagem foi processada com sucesso
false,
false,
$callback // Função de tratamento de mensagem
);
// Bloquear o processo até que o canal não seja fechado, para evitar a saída do processo
while ($channel->is_open()) {
$channel->wait();
}
// Liberar recursos
$channel->close();
$connection->close();