В предыдущей главе мы рассмотрели наиболее подходящий для начинающих учебник по RabbitMQ+PHP (5) типы обменников. Мы использовали direct обменник (прямой обменник), который позволяет маршрутизировать сообщения по ключам маршрутизации, но это было недостаточно гибко, так как он мог только осуществлять точное совпадение. В этой главе мы вводим Topic обменник (тематический обменник), который поддерживает нечеткое совпадение ключей маршрутизации.
В предыдущей статье мы реализовали отправку одного сообщения производителем, которое одновременно передается всем очередям. Однако иногда мы не хотим, чтобы все сообщения передавались всем очередям. Мы хотим, чтобы сообщения определенного типа (например, типа "a") передавались только очереди A, а сообщения другого типа (например, типа "b") передавались только очереди B и C. Фан-образный обменник просто рассылает сообщения всем потребителям, фактически рассылая их всем связанным очередям.
Чтобы реализовать эту функциональность, можно создать несколько обменников, что является простым и жестким подходом, но не гибким. В этой главе мы рассмотрим использование одного прямого обменника и маршрутизации для реализации этой функциональности.### Условия ключей маршрутизации для Topic обменника (тематического обменника)
routing_key
(ключ маршрутизации). Он должен состоять из списка слов, разделенных точками (.
). Слова могут быть произвольными, но обычно они определяются типом текущего сообщения. Некоторые примеры эффективных ключей маршрутизации: stock.usd.nyse
, nyse.vmw
, quick.orange.rabbit
. Ключ маршрутизации может содержать произвольное количество слов, но не более 255 байт.одинаковую
форму. Логика тематического обменника похожа на логику прямого обменника
- сообщения, отправленные с определенным ключом маршрутизации
, передаются в очередь, привязанную к совпадающему ключу привязки
. Однако ключи привязки имеют два важных специальных случая:
*
(звезда) может заменить одно слово#
(решетка) может заменить ноль или более слов### Принцип работы тематического обменника (Topic обменника)
Прямой обменник (direct обменник) использует правила маршрутизации, которые требуют точного совпадения routing_key
(ключа маршрутизации) и binding_key
(ключа привязки). Однако это совпадение не удовлетворяет некоторые специфические бизнес-логики. Поэтому мы можем использовать тематический обменник (Topic обменник), который отличается изменением правил совпадения:routing_key
(ключ маршрутизации) состоит из слов, разделенных точками (.
).binding_key
(ключ привязки) также состоит из слов, разделенных точками (.
). Правила совпадения используют *
и #
для нечеткого совпадения, например: *.user.*
, *.*.log
, user.#
.```
routing_key=list1.user.two
routing_key=list2.user.three
routing_key=user.name.one
routing_key=user.name.two
routing_key=test.test1.log
routing_key=test2.test3.log
На основе изображения выше можно сделать вывод, что сообщения с маршрутизационным ключом "list1.user.two" и "list2.user.three" будут доставлены в очередь `queue_topic_1`, а сообщения с ключами "user.name.one", "user.name.two", "test.test1.log" и "test2.test3.log" будут отправлены в очередь `queue_topic_2`. Если маршрутный ключ не соответствует ни одному из указанных правил, сообщение будет отброшено, так как оно не соответствует ни одному из привязок.### Краткое резюме Тематического обмена
> Тематический обменник обладает широкими возможностями. Когда очередь привязана к "#" и соответствует ключу привязки — он получает все сообщения, независимо от маршрутизационного ключа, как в случае с фан-аут обменником; когда специальные символы "*" и "#" не используются в привязке, тематический обменник работает как прямой обменник. Давайте рассмотрим практические примеры использования тематического обмена!
### Примеры кода для Тематического обмена
1. Пример неправильных правил соответствия:


2. Пример соответствия с использованием символа "*":

3. Пример соответствия с использованием символа "*" для последнего разделителя:


Демонстрация соответствия правилам #4


(1) Настройка имени очереди для приема сообщений
```php
public function setQueueName($queue_name = "",$passive = false,$durable = false,$exclusive = true,$auto_delete = false)
{
if(!$queue_name) return false;
$this->amqp_channel->queue_declare($queue_name, $passive, $durable, $exclusive, $auto_delete);
$this->queue_name = $queue_name;
}
(2) Привязка очереди к обменнику (обратите внимание, что можно привязать несколько)
public function bindQueue($queue_name = '',$exchange_name = '',$binding_routing_key = '')
{
if(!$exchange_name || !$binding_routing_key) return false;
if(!$queue_name) $queue_name = $this->queue_name;
}
``````php
// Циклическая привязка нескольких ключей маршрутизации
if (is_array($binding_routing_key)) {
foreach ($binding_routing_key as $key => $binding_key) {
$this->amqp_channel->queue_bind($queue_name, $exchange_name, $binding_key);
}
return true;
}
$this->amqp_channel->queue_bind($queue_name, $exchange_name, $binding_routing_key);
}
(3) Настройка имени очереди для приема сообщений
public function sendMessage($exchange_name = '', $routing_key = '')
{
if (!$exchange_name || !$routing_key) return false;
$message = "message: Hello phpassn!'\nКачественная поделка оригинальных статей";
for ($i = 0; $i <= 10; $i++) {
$amqp_message = new AMQPMessage($message);
$this->amqp_channel->basic_publish($amqp_message, $exchange_name, $routing_key);
echo $routing_key . " -- Send 'Hello phpassn!'\nКачественная поделка оригинальных статей -- " . $i;
}
}
```Заключение: `Topic Exchange (тематический обменник)` иногда может выполнять функции прямого обменника, но чаще используется для различных целей, что делает его одним из наиболее часто используемых. Например, в проектах нашей компании мы используем тематический обменник. Для тех, кто хочет дополнить свои знания, следующая глава будет посвящена `Реализация RPC-модели RabbitMQ`. Не упустите эту возможность, следите за обновлениями!
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )