Rabbitmq - topic模式(通配符模式)

绑定键有两个重要的特殊情况:

  • '*'(星号)可以只替换一个单词。
  • '#' (hash) 可以代替零个或多个单词。

示例:

消息将使用由三个单词(两个点)组成的路由键发送。路由键中的第一个词将描述速度,第二个是颜色,第三个是物种:"speed.colour.species"。
绑定可以概括为:

  • 队列Q1 对所有橙色动物都感兴趣。
  • 队列Q2 想听听关于兔子的一切,以及关于懒惰动物的一切。

路由键设置为“ quick.orange.rabbit ”的消息将被传递到两个队列。
消息“lazy.orange.elephant ”也将发送给他们两个。另一方面,“ quick.orange.fox ”只会进入Q1,而“ lazy.brown.fox ”只会进入Q2。“ lazy.pink.rabbit ”只会被传递到Q2一次,即使它匹配两个绑定。“ quick.brown.fox ” 不匹配任何绑定,因此将被丢弃。
如果我们违反合同并发送带有一四个单词的消息,例如“ orange ”或“ quick.orange.male.rabbit ”,这些消息不会匹配任何绑定并且会丢失。另一方面,“ lazy.orange.male.rabbit ”,即使它有四个单词,也会匹配最后一个绑定,并被传递到Q2

生产者

<?php
require_once __DIR__ . '/vendor/autoload.php';

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

$v_host = 'test';
$exc_name = 'topic-exc'; //交换器名
$routing_key = 'goods.store';
//地址 端口 用户名 密码 vhost
$connection = new AMQPStreamConnection('localhost', 5672, 'rabbitmq', 'rabbitmq', $v_host);

//新建通道
$channel = $connection->channel();
//声明交换器 参数:交换器名、模式、不存在则自动创建、持久化、不自动消亡
$channel->exchange_declare($exc_name, 'topic', false, true, false);

//消息 参数:消息 、持久化
$data = 'this is good.store message';
$msg = new AMQPMessage($data, [
    'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT
]);
//将消息推送到交换器里
$channel->basic_publish($msg, $exc_name, $routing_key);

//关闭通道
$channel->close();
$connection->close();

消费者

<?php
require_once __DIR__ . '/vendor/autoload.php';

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

$v_host = 'test';
$exc_name = 'topic-exc'; //交换器名
$routing_key = 'goods.*';
//地址 端口 用户名 密码 vhost
$connection = new AMQPStreamConnection('localhost', 5672, 'rabbitmq', 'rabbitmq', $v_host);

//新建通道
$channel = $connection->channel();
//声明交换器 参数:交换器名、模式、不存在则自动创建、持久化、不自动消亡
$channel->exchange_declare($exc_name, 'topic', false, true, false);

//随机生成队列名(生成后返回的是数组,只有第一个元素是队列名) 临时生成的,退出程序则消失
list($queue_name,,) = $channel->queue_declare('', false, false, true, false);

$channel->queue_bind($queue_name, $exc_name, $routing_key);

$callback = function ($msg) {
    var_dump('received :' . $msg->body);
    $msg->ack();
};
//一次只消费一条消息,未确认消费前不可消费其他消息
$channel->basic_qos(null, 1, null);

$channel->basic_consume($queue_name, '', false, false, false, false, $callback);

while ($channel->is_open()) {
    $channel->wait();
}
//关闭通道
$channel->close();

posted @ 2022-08-23 16:00  Myifb  阅读(163)  评论(0)    收藏  举报