资讯专栏INFORMATION COLUMN

RabbitMQ+PHP 教程五(Topics)

nemo / 2883人阅读

摘要:前提必读本教程假设是安装在标准端口上运行。这些词可以是任何东西,但通常它们指定连接到消息的某些特性。如果我们违背合同,用一个或四个词,如或那么,这些消息将不匹配任何绑定并将丢失。代码与前面的教程几乎相同。

(using php-amqplib)

前提必读

本教程假设RabbitMQ是安装在标准端口上运行(5672)。如果您使用不同的主机、端口或凭据,则连接设置需要调整。

在哪里得到帮助

如果您在本教程中遇到困难,可以通过邮件列表与我们联系。

开始

在前面的教程中,我们改进了日志系统。我们使用的是一种直接广播方式,而不是只使用一种直接(direct)广播方式的fanout交换机,从而获得了有选择地接收日志的可能性。

虽然使用直接direct交换机改进了我们的系统,但它仍然有局限性——它不能根据多个标准进行路由。

在我们的日志系统中,我们可能希望订阅基于严重性的日志,但也要基于发出日志的源。你可能从syslog UNIX工具知道这个概念,路由日志基于严重性(info/warn/crit…)和设备(auth/cron/kern…)。

这会给我们很大的灵活性,我们可能要听关键的错误来自kern, 所有日志来自kern”。

为了在日志系统中实现这一点,我们需要了解一个更复杂的主题topic交换机。

Topic exchange

发送到一个话题交换机(topic exchange)信息,不能是任意routing_key -它必须是一个单词的列表,用逗号分隔。这些词可以是任何东西,但通常它们指定连接到消息的某些特性。一些有效的路由键的例子:stock.usd.nysenyse.vmw"quick.orange.rabbit"。在你喜欢的路由键中,最多可以有255个字节的单词。

绑定键也必须是相同的形式。主题交换背后的逻辑类似于一个直接的消息,用特定的路由键发送的消息将被发送到绑定到绑定键的所有队列中。但是有两个重要的绑定键的特殊情况:

*(星号)可以代替一个词。
#(哈希)可以代替零个或更多的单词。

在一个例子中解释这一点是最容易的:

在这个示例中,我们将发送所有描述动物的消息。消息将用一个包含三个单词(两个点)的路由键发送。路由键中的第一个字将描述速度,第二个颜色和第三个种:..

我们创建三的绑定:Q1绑定绑定键*.orange.* 和 Q2 with *.*.rabbitlazy.#

这些绑定可以概括为:

Q1对所有的橙色(orange)动物很感兴趣。
Q2想听关于兔子(rabbits)的一切,关于懒惰(lazy)动物的一切。

带有quick.orange.rabbit的路由键的消息将传送到两个队列中。信息lazy.orange.elephant也将去他们俩。另一方面,quick.orange.fox只会进入第一排,而lazy.brown.fox只到第二个。lazy.pink.rabbit将被送到第二个队列只有一次,即使它匹配两个绑定。quick.brown.fox不匹配任何绑定,所以它将被丢弃。

如果我们违背合同,用一个或四个词,如orangequick.orange.male.rabbit?那么,这些消息将不匹配任何绑定并将丢失。

另一方面,lazy.orange.male.rabbit,即使它有四个词,将匹配最后的绑定,并将交付给第二个队列。

Topic exchange

主题交换(Topic exchange)功能强大,可以像其他交换机一样。

当队列绑定#(hash)绑定键-它将收到的所有邮件,不管路由关键一样的fanout交换机。

当特殊字符*(star)和#(hash)中不使用绑定,主题交换机会表现的像一个direct交换机。

汇总(Putting it all together)

我们将在日志系统中使用主题交换机(topic exchange)。我们将从一个工作假设开始,假设日志的路由键有两个词:.

代码与前面的教程几乎相同。

emit_log_topic.php代码:

channel();

$channel->exchange_declare("topic_logs", "topic", false, false, false);

$routing_key = isset($argv[1]) && !empty($argv[1]) ? $argv[1] : "anonymous.info";
$data = implode(" ", array_slice($argv, 2));
if(empty($data)) $data = "Hello World!";

$msg = new AMQPMessage($data);

$channel->basic_publish($msg, "topic_logs", $routing_key);

echo " [x] Sent ",$routing_key,":",$data," 
";

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

?>

receive_logs_topic.php代码:

channel();

$channel->exchange_declare("topic_logs", "topic", false, false, false);

list($queue_name, ,) = $channel->queue_declare("", false, false, true, false);

$binding_keys = array_slice($argv, 1);
if( empty($binding_keys )) {
    file_put_contents("php://stderr", "Usage: $argv[0] [binding_key]
");
    exit(1);
}

foreach($binding_keys as $binding_key) {
    $channel->queue_bind($queue_name, "topic_logs", $binding_key);
}

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

$callback = function($msg){
  echo " [x] ",$msg->delivery_info["routing_key"], ":", $msg->body, "
";
};

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

while(count($channel->callbacks)) {
    $channel->wait();
}

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

?>

接收所有日志:

php receive_logs_topic.php "#"

接受所有的日志来自kern

php receive_logs_topic.php "kern.*"

或者,如果您只想听关于critical的日志:

php receive_logs_topic.php "*.critical"

你可以创建多个绑定:

php receive_logs_topic.php "kern.*" "*.critical"

触发一个日志来自路由键kern.critical类型

php emit_log_topic.php "kern.critical" "A critical kernel error"

这些程序让我们觉得很好玩。请注意,代码对路由或绑定键不作任何假设,您可能希望使用两个以上的路由键参数。

(全部源码:emit_log_topic.php 和 receive_logs_topic)

接下来,了解如何通过一个远程过程调用来执行往返消息,你可以阅读下一章节:RabbitMQ+PHP 教程六(RPC)。

翻译来自 RabbitMQ - RabbitMQ tutorial - Topics

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/28315.html

相关文章

  • RabbitMQ+PHP 教程四(Routing)

    摘要:我们以前的教程中的日志系统将所有消息广播给所有消费者。我们希望扩展这一点,允许基于其一定严重性程度来过滤消息。在这种情况下,交换机将表现为交换机,并将消息发送到所有匹配队列。 using php-amqplib 前提必读 本教程假设 RabbitMQ 是运行在标准端口上运行(5672). 如果您使用不同的主机、端口或凭据,则连接设置需要调整。 如果您在本教程中遇到困难,可以通过邮件列...

    pinecone 评论0 收藏0
  • rabbitmq中文教程python版 - Topics

    摘要:单词可以是任何东西,但通常它们指定了与该消息相关的一些功能。消息将使用由三个字两个点组成的路由键发送。另一方面,只会进入第一个队列,而只会进入第二个队列。不匹配任何绑定,因此将被丢弃。代码几乎与前一个教程中的代码相同。 源码:https://github.com/ltoddy/rabbitmq-tutorial Topics (using the Pika Python client)...

    ernest.wang 评论0 收藏0
  • RabbitMQ+PHP 教程一(Hello World)

    摘要:在中间的框是一个队列的消息缓冲区,保持代表的消费。本教程介绍,这是一个开放的通用的协议消息。我们将在本教程中使用,解决依赖管理。发送者将连接到,发送一条消息,然后退出。注意,这与发送发布的队列匹配。 介绍 RabbitMQ是一个消息代理器:它接受和转发消息。你可以把它当作一个邮局:当你把邮件放在信箱里时,你可以肯定邮差先生最终会把邮件送到你的收件人那里。在这个比喻中,RabbitMQ就...

    silencezwm 评论0 收藏0
  • RabbitMQ】——centos7安装rabbitmq教程 以及 PHP开启rabbitmq扩展

    摘要:第一步安装因为是语言编写的,所以我们首先需要安装第二步安装官网提供的安装方式本人安装成功的方式第三步查看是否已经安装好了,能查到说明已经安装完成了。 第一步:安装Erlang 因为rabbitMQ是Erlang语言编写的,所以我们首先需要安装Erlang rpm -Uvh http://www.rabbitmq.com/releases/erlang/erlang-18.1-1.el...

    Carl 评论0 收藏0
  • RabbitMQ】——centos7安装rabbitmq教程 以及 PHP开启rabbitmq扩展

    摘要:第一步安装因为是语言编写的,所以我们首先需要安装第二步安装官网提供的安装方式本人安装成功的方式第三步查看是否已经安装好了,能查到说明已经安装完成了。 第一步:安装Erlang 因为rabbitMQ是Erlang语言编写的,所以我们首先需要安装Erlang rpm -Uvh http://www.rabbitmq.com/releases/erlang/erlang-18.1-1.el...

    FuisonDesign 评论0 收藏0

发表评论

0条评论

nemo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<