RabbitMQ学习笔记(五)之Topics
上一节中,使用Dircet Exchange结合routingKey及bindingKey可以实现选择性地接收消息。但是它也有局限性,无法基于多种尺度来路由。
比如说日志系统中我们可能不仅希望根据级别,还希望根据日志发出者的身份来进行路由。比如syslog unix
工具,就是根据severity和facility(auth/cron/kern…)来进行路由的。
这各方式更具灵活性,比如我想接收来自cron的Error信息和来自Kern的所有信息。
要实现这样的功能我们需要学习更复杂的Topic exchange。
Topic exchange
发送给topic exchange的信息的routingKey必须是一个word的list,用.号分隔。习惯上用一些能够代表消息特征单词来作为word,比如stock.usd.nyse
是一个合法的routingKey。word不限个数,但总长不能超过255 Byte。
bindingKey也必须是这样的形式,而路由逻辑则和Direct方式相似,消息将被发送给所有bindingKey和RoutingKey匹配的队列。但是有两wildcard:
\* 能替换成任何一个(单个)word
# 能替换成任意(0-n)个word
应用案例
以下的例子是,消息都是描述动物的,由三个word组成,第一个描述速度,第二个描述颜色,第三个描述种类。即
创建Binding x 2:
- Q1: *.orange.*
- Q2 *.*.rabbit + lazy.# (两个BindingKey)
关于以上Binding的解释:
- Q1对所有橙色动物感兴趣
- Q2对兔子和懒惰动物感兴趣
routingKey = quick.orange.rabbit
的消息将同时发送给Q1和Q2,lazy.orange.elephant
也是。quick.orange.fox
只发给Q1,lazy.pink.rabbit
只给Q2,且只发送一次(虽然两个BindingKey都匹配),quick.brown.fox
将被丢弃。
如果我们发送不合预期格式的消息呢?比如routingKey = orange
或quick.orange.male.rabbit
?因为不匹配任何BindingKey,所以消息会被丢弃。
也就是说lazy.orange.male.rabbit
将匹配Q2的第二个Binding,因为会被Q2收到。
Topic exchange
Topic Exchange功能强大,可配置成像其它几种Exchange一样工作。
BindingKey=#,将成为fanout。
如果不使用#和*这样的符号,那么就成为了direct。
汇总
回到之前日志系统,我们的routing key有两个words: <facility>.<severity>
。
代码和上一节,除了更换Exchange类型,基本一样。
先看运行效果,bindingkey和消息的routingKey都是在参数中指定的。
可以看到实现了预期的效果。
因为和上一节一样(只更改Exchange类型),所以就不再帖了。