Topics
在上一节教学中,我们改善了日志系统。我们由只能使用虚拟广播的 fanout
交换机改为了 direct
类型,并且获得了选择性接收消息的可能性。
尽管使用直连交换机改善了系统,但它依然有限制 – 它不能基于多标准路由。
在我们的日志系统,可能不仅仅想要订阅基于日志严重性的消息,还希望基于日志的发出源订阅。你或许从 syslog
unix 工具了解到这一概念,它基于日志的严重性和产生的设备来路由日志。
那将带给我们很多灵活性,我们可能需要监听来自 cron
的严重错误和来自 kern
的所有日志。
为了在我们的日志系统中完成这个,我们需要了解更加灵活的 topic
交换机。
Topic 交换机
发送到 topic
交换机的消息不能有任意的 routing_key
– 它必须是一系列单词,且用点隔开。单词可以是任意的(包括数字),通常是一些与消息有关的特定特征词。一些有效的路由键如:stock.usd.nyse
,nyse.vmw
,quick.orange.rabbit
。在路由键中可以许多单词,上限是 255 字节。
绑定键也必须是相同的格式。topic
交换机背后的逻辑类似于 direct
的,一个带有特定路由键的消息将会被发送到绑定匹配绑定键的所有队列。这里有两个关于绑定键的关键点。
*
可以订阅特定的单个单词。#
剋订阅从零个到多个单词。
下图的例子解释起来更简单:
这个例子中我们将发送一些关于动物描述的消息。发送的消息带有的路由键由 3 个单词组成(两个点)。路由键的第一个单词描述速度,第二个是颜色,第三个是动物的种类:<speed>.<colour>.<species>
我们创建了 3 个绑定:Q1 绑定了 *.range.*
,Q2 绑定了 *.*.rabbit
和 lazy.#
。
这些绑定可以总结为:
- Q1 对所有橙色动物感兴趣
- Q2 监听所有关于兔子的消息,以及所有与懒有关的动物
一个带有 quick.orange.rabbit
路由键的消息会发送这两个队列。带有 lazy.orange.elephant
的消息也会发送到这两个队列。另一方面,quick.orange.fox
将仅会发送到第一个队列,而 lazy.brown.fox
仅会发送到第二个队列。lazy.pink.rabbit
只会发送到第二个队列一次,即使它匹配了两个绑定。quick.borwn.fox
不匹配任何一个队列的绑定,就会被抛弃。
如果我们打破约定,发送了一个带一个或者四个词的消息,比如:orange
或者 quick.orange.male.rabbit
?当然,这些消息不匹配任何绑定,并会丢失。
但是 lazy.orange.male.rabbit
,即使有四个词,它依然匹配最后一个绑定,并会发送到第二个队列。
Topic exchange
Topic 交换机功能强大,可以像其他类型的交换机一样运行。
当一个队列使用#
作为绑定键,它将会无视任何路由键,收到所有的消息—就像fanout
交换机。
当特殊的字符*
与#
并没有用在绑定上,topic
交换机跟 直连的没有什么区别。
总结
在我们日志系统中将使用 topic
交换机,假设日志消息的路由键由两个词组成:<facility>.<severity>
。
emit_log_topic.php
代码如下:
receive_logs_topic.php
代码如下:
接收全部的日志:
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"
接下来,在 教程6 中找出如何作为远程过程调用来执行往返消息。
翻译自:
1.https://www.rabbitmq.com/tutorials/tutorial-five-php.html