本文对应 RabbitMQ 官方教程的第五个例子——Topics(主题),讲述怎么基于模式(主题)来接收消息。
主题(Topics)
在上一个教程中,我们改进了日志系统,我们使用了 direct
交换器来代替 fanout
交换器,
因为fanout
交换器只能广播消息,而 direct
交换器可以实现选择性地接收消息。
虽然使用 direct
交换器 改进了我们的系统,但它仍然有局限性——它不能基于多个条件进行路由。
在我们的日志记录系统中,我们可能不仅要根据严重性来订阅日志,还要根据发出日志的源来订阅日志。
您可能从syslog unix工具中了解这个概念,
该工具根据 severity(info / warn / crit …)和 facility(auth / cron / kern …)来路由日志。
这会给我们带来很大的灵活性 - 我们可能想要听取来自 ‘cron’ 的关键错误以及来自 ‘kern’ 的所有日志。
要在我们的日志记录系统中实现这一点,我们需要了解更复杂的 topic
交换器。
主题交换器(Topic exchange)
发送到 topic
交换器的消息不能随意指定 routing key(路由键)
,它必须是一个由点分割的单词列表,
这些单词可以是任意内容,但通常会在其中指定一些与消息相关的特性。
请看一些合法的路由键示例:stock.usd.nyse
,nyse.vmw
,quick.orange.rabbit
,
路由键可以包含任意数量的单词,但不能超过 255 个字节的上限。
binding key(绑定键)
也必须是相同的形式,topic
交换器的背后逻辑与 direct
交换器类似,
使用指定路由键发送的消息会被分发到与其绑定键匹配的所有队列中。
不过对于绑定键来说,有两个重要的特殊情况需要注意:
*
(星号)可以代替一个单词。#
(哈希)可以代替零个或多个单词。
下图示例是对上述内容最简单的解释:
在这个例子中,我们将发送所有描述动物的消息。
消息将与包含三个单词(两个点)的路由键一起发送。
路由键中的第一个单词将描述速度,第二个是颜色,第三个是物种,
即:speed
.colour
.species
我们创建了三个绑定规则绑定到两个队列:
Q1 绑定了键 .orange.
Q2 绑定了键 *.*.rabbit
和 lazy.#
这些绑定可以被概括为:
- 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
的消息,
尽管它有四个单词,也会匹配最后一个绑定,并将被发送到第二个队列。
Topics 交换器
topic交换器的功能是很强大的,它可以表现出一些其他交换器的行为。
当一个队列与键#
绑定时, 它会忽略路由键,接收所有消息,这就像fanout
交换器一样。
当特殊字符*
和#
未在绑定中使用时,topic
交换器的行为就像direct
交换器一样。
完整演示
为了更好地演示,下面的代码和官方教程的不同。
官方例子传送门
派糖者
代码:
1 | using System; |
熊孩子
代码:
1 | using System; |
启动一个喜欢吃软
糖的熊孩子
:1
2\Child\bin\Debug\netcoreapp2.2> dotnet Child.dll 软.#
[Consumer(消费者),我喜欢吃的糖果是 软.#]:我的心在等待,永远在等待...
启动一个喜欢吃硬巧克力
糖的熊孩子
:1
2\Child\bin\Debug\netcoreapp2.2> dotnet Child.dll 硬.*.巧克力
[Consumer(消费者),我喜欢吃的糖果是 硬.*.巧克力]:我的心在等待,永远在等待...
启动一个什么糖都喜欢吃的熊孩子
:1
2\Child\bin\Debug\netcoreapp2.2> dotnet Child.dll
[Consumer(消费者),我喜欢吃的糖果是 ]:我的心在等待,永远在等待...
启动派糖者
:1
2
3
4\CandyKeeper\bin\Debug\netcoreapp2.2> dotnet CandyKeeper.dll
请输入糖的特征与祝福语:软硬.颜色.味道 祝福语
如:软.红.草莓味 快乐成长
如:硬.灰.巧克力 身体健康
派糖者
开始派糖:1
2软.粉红.巧克力 健康快乐
[Producer(生产者,派糖者)] 派出一些礼物: 糖果:软.粉红.巧克力 祝福语:健康快乐
哪些熊孩子
会收到这些礼物呢?
结束语
下一章是将 MQ 中的 RPG,会有惊喜哦。