rabbitMq学习笔记(5) 主题交换器

在上一篇文章中,我们对之前的日志系统进行了改进,使用direct类型的exchange替代了只能广播消息的fanout类型,让日志系统能够有选择性的接收处理消息。

虽然使用direct类型的exchange提升了日志系统的扩展性,但还是有它的局限性存在,那就是无法配置多重标准的路由。

如果想让系统不能仅根据日志级别来定义,还能根据发送日志的源信息来订阅。如unix工具syslog,就是根据日志级别(info/warn/crit..)和设备(auth/cron/kern)来进行路由的。这会提供更多的灵活性,如可以做到监听所有来自’cron’和’kern’设备的error信息。

为了实现这种灵活性,需要来学习下另外一个功能更综合的topic类型的交换器(exchange).

Topic exchange

Topic类型的exchange消息的routing key是有一定限制的,必须是一组使用“.”分开的单词。单词可以是任意的,但是一般来说以能准确的表达功能的为佳。如以下的例子都是合法的:”stock.usd.nyse”, “nyse.vmw”,”quick.orange.rabbit”.Routing key可以是任意多个单词组成,但其总长度不能超过255个字节。

Topic exchange的binding key跟之前的没有太大区别,其逻辑跟direct一样,其接收到的消息会分发到所有与其routing key相匹配的绑定队列。以下两个通配符也可作为binding key使用:

看例子:

上图中,消息的routing key用三个单词来表示,依次表示速度、颜色、种类,其形式如:”..”。

图中有三个绑定:Q1的绑定键是”.orange.“, Q2的绑定键是”..rabbit”和”lazy.#”.

这三个绑定规则可以简单概括为:

  • Q1对orange颜色的动物感兴趣;
  • Q2则对所有物种是rabbit的、速度是lazy的所有动物感兴趣;

举例来说明带有不同routing key的消息会被路由到哪个队列:

Topic exchange

Topic exchange很灵活,也很容易用此实现其他类型的功能.

如果将”#”指定为绑定键,那么就会接收所有的消息,相当于fanout类型的广播;

如果通配符”*”,”#”均不作为绑定键使用,那么其功能实现就等同于direct类型;

整个文件

在前一篇的基础上实现topic exchange,只需做少许改的即可,这里我们假设routing key由两个单词组成,类似于”.“.

emit_log_topic.go:

Github地址

receive_logs_topic.go:

Github地址

运行:

接收所有消息:

go run receive_logs_topic.go “#”

接收来自”kern”设备的消息:

go run receive_logs_topic.go “kern.*”

接收所有以”critical”结尾的消息:

go run receive_logs_topic.go “*.critical”

创建多重绑定:

go run receive_logs_topic.go “kern.” “.critical”

发送消息:

go run emit_log_topic.go “kern.critical” “A critical kernal error”

上述假设都是基于两个单词的,你也可以试一下设置其他长度单词的routing key看看会发生什么。

下一篇文章将会介绍如何使用RPC(Remote Procedure call)来消费消息。

发表评论

电子邮件地址不会被公开。 必填项已用*标注