乐趣区

关于rabbitmq:RabbitMQ-路由模式的使用

路由模式与公布订阅相似,区别是公布订阅替换机会将所有音讯播送给所有消费者绑定的队列,消费者生产全副音讯;而路由模式交换机只会将与路由键齐全匹配的音讯发送给消费者绑定的队列,消费者只生产该类音讯。

装置依赖

# composer.json
{
    "require": {"php-amqplib/php-amqplib": ">=3.0"}
}
> composer.phar install

模式构造

路由模式应用的是 direct 交换机,这个交换机的路由算法也很简略,将它收到的所有音讯进入绑定键与音讯的路由键齐全匹配的队列。

生产者

生产者连贯到 RabbitMQ,发送一条音讯,而后退出。

# send.php

<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

// 创立连贯
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');

// 创立通道
$channel = $connection->channel();

// 定义一个名为 direct_logs 的 direct 交换机
$channel->exchange_declare('direct_logs', 'direct', false, false, false);

// 从参数中获取交换机的路由键
$severity = isset($argv[1]) && !empty($argv[1]) ? $argv[1] : 'info';

$data = implode(' ', array_slice($argv, 2));
if (empty($data)) {$data = "Hello World!";}

// 
$msg = new AMQPMessage($data);

// 通过名为 direct_logs 的 direct 交换机发送音讯到队列 (音讯内容, 交换机, 路由键);
$channel->basic_publish($msg, 'direct_logs', $severity);

echo '[x] Sent', $severity, ':', $data, "\n";

$channel->close();
$connection->close();

消费者

消费者监听来自 RabbitMQ 的音讯,通常须要始终放弃运行状态以监听音讯。

# receive.php

<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;

// 创立连贯
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');

// 创立通道
$channel = $connection->channel();

// 定义一个名为 direct_logs 的 direct 交换机
$channel->exchange_declare('direct_logs', 'direct', false, false, false);

// 创立一个随机命名的新队列,第三个参数为敞开队列长久化,第四个参数为当申明它的连贯敞开时队列会被主动删除
list($queue_name, ,) = $channel->queue_declare("", false, false, true, false);

// 定义所有的绑定键
$severities = array_slice($argv, 1);
if (empty($severities)) {file_put_contents('php://stderr', "Usage: $argv[0] [info] [warning] [error]\n");
    exit(1);
}

// 将随机命名的队列绑定到 direct 交换机,生产者向交换机发送音讯将被放到绑定的队列中
foreach ($severities as $severity) {$channel->queue_bind($queue_name, 'direct_logs', $severity);
}

echo "[*] Waiting for logs. To exit press CTRL+C\n";

// 定义回调函数
$callback = function ($msg) {echo '[x]', $msg->delivery_info['routing_key'], ':', $msg->body, "\n";
};

// 第四个参数设为 true 开启主动音讯确认,即投递音讯后立即标记为删除
$channel->basic_consume($queue_name, '', false, true, false, false, $callback);

while ($channel->is_open()) {$channel->wait();
}

$channel->close();
$connection->close();

运行

关上一个终端,运行消费者,接管正告和谬误的音讯:

php receive.php warning error > logs_from_rabbit.log

关上另一个终端,运行消费者,接管信息、正告和谬误的音讯:

php receive.php info warning error
# => [*] Waiting for logs. To exit press CTRL+C

关上另一个终端,运行生产者,发送谬误音讯:

php send.php error "Run. Run. Or it will explode."

查看所有交换机

sudo rabbitmqctl list_exchanges

查看所有的绑定关系

sudo rabbitmqctl list_bindings
退出移动版