四. RabbitMQ路由解析

什么是路由呢?就和你们家里的路由器是一个概念,路由器就是把网络信号做转发、那么RabbitMQ中的路由,就是把消息做转发;

RabbitMQ一共提供了四种路由:

Ø Direct类型

Ø Fanout类型

Ø Topic类型

Ø Header类型

 

 

01Direct类型的路由:

上一篇文章中写的RabbitMQ的基本应用案例中使用的Exchange就是direct类型的,direct类型的exchange路由规则很简单:

exchange在和queue进行binding时会设置routingkey(为了避免和下边的routingKey混淆,很多时候把这里的routingKey叫做BindingKey)

 

channel.QueueBind(queue:"Q1",exchange:"myexchange",routingKey:"orange");将消息发送到Broker时会设置对应的routingkey:channel.BasicPublish(exchange:"myexchange",routingKey:"orange",basicProperties: null, body: body);

 

只有RoutingKey和BindingKey完全相同时,exchange才会把消息路由到绑定的queue中去

 

我们知道了direact类型的交换机只有routingKey和bindingKey相同的时候才会进行消息路由,根据这一特点我们可以通过routingKey将消息路由到不同的queue中。如在进行日志处理时,需求是所有的日志都保存到文本文件,出现错误日志时则还需要短信通知以便及时处理。

 

我们可以创建两个队列:只接收错误日志的log_error队列和接收所有日志信息的log_all队列。消费者C1处理log_error队列中消息,将这些消息通过短信通知管理员,消费者C2处理log_all队列的信息,将这些信息记录到文本文件。如下图所示:

 

生产者用于发送日志消息,代码下图所示:

如果图片不清晰,请关注朝夕net社区微信公众号获取视频录播

 

消费者C1用于处理log_error队列中的消息,错误消息进行短信通知,代码如下:

 

消费者C2用于处理log_all队列中的消息,所有消息记录到文本文件中,代码下图所示:

生产者,消费者同时运行起来,结果如图6:

 

 

02 Fonout类型的路由:

fanout类型的exchange路由规则是最简单的,交换机会把消息广播到与该Exchange绑定的所有queue中,即所有和该exchange绑定的队列都会收到消息。fanout类型exchange和队列绑定时不需要指定routingKey,即使指定了routingKey也会被忽略掉。路由结构如下图:

fanout类型交换机主要用于发布/订阅的一些场景,如用户注册了我们的网站后,我们通过短信和邮件两种方式通知用户;

 

代码如下图:

这里通过代码简单演示将消息同时使用短信和邮件两种方式通知用户的流程。首先声明一个fanout类型的exchange,然后声明两个队列 SMSqueue和EMAILqueue,这两个队列都和这个exchange绑定。消费者1处理EMAILqueue的消息,通过邮件方式发送通知;消费者2处理SMSqueue的消息通过短信方式发送通知。

生产者代码:

 

消费者1将EMAILqueue的消息通过邮件方式发送通知,代码如下图:

      消费者2将SMSqueue的消息通过短信方式发送通知,代码如下图:

 

启动这三个应用程序,执行结果如下图

03 Topic类型的路由:

topic类型exchange的路由规则也是基于routingKey和bindingKey的,其路由过程和direct类型基本一致,两者的区别在于direct类型的exchange要求routingKey和bindingKey必须相同才进行将消息路由到绑定的queue中,而topic类型的bindingKey是一个匹配规则,只要routingKey符合bindingKey的规则就可以将消息路由到绑定的queue中去,结构如下图所示。

 

注意routingKey和bindingKey的结构都是一系列由点号连接单词的字符串。

例如【aaa.bbb.ccc】bindingKey的两个特殊符号:*表示一个单词,#表示0或多个单词(注意是单词,而不是字符)。如下图,usa.news和usa.weather都和usa.#匹配,而usa.news和europe.news都和#.news匹配。如下图所示;

代码实现如下图所示:这里使用代码实现上图中的例子,为了方便我们只定义两个队列:接收美国相关信息的usaQueue(bindingKey是usa.#)和接收新闻消息的newsQueue(bindingKey是#.news)。然后定义两个消费者,消费者1处理useaQueue的消息,消费者2处理newsQueue的消息。

 

生产者代码:如下图所示

然后我这里提供有多个消费者。

 

消费者1代码如下图,只处理usaQueue中的消息

 

消费者2代码如下图,只处理newsQueue中的消息:

生成者发送的四条消息中,消息1的routingKey为usa.news,同时符合usaQueue的bindingKey(usa.#)和newsQueue的bindingKey(#.news),所以消息1同时路由到两个队列中;消息2的routingKey为usa.weather只符合usa.#,发送到usaQueue;消息的rouKey为europe.news,只符合#.news,发送到newsQueue中;消息4的routingKey为europe.weahter,和两个队列的bindingKey都不符合,所以被丢弃。执行这三个Console应用程序,结果如下图。

注:一点补充:topic类型交换机十分灵活,可以轻松实现direct和fanout类型交换机的功能。如果绑定队列时所有的bindingKey都是#,则交换机和fanout类型交换机表现一致;如果所有的bindingKey都不包含*和#,则交换机和direct类型交换机表现一致。

04 Header类型的路由:

Hearder路由是一种比较特别的路由,header类型路由规则和上边的几种exchange都不一样,header类型exchange不是通过routingKey进行路由的,而是通过Headers。exchange在和queue进行binding时可以设置arguments:如下图所示;

 将消息发送到exchange时可以设置消息的Header:如下图

user和pass是普通的键值对,我们也可以设置其他的键值对。x-match是一个特殊的属性,当x-match为all时,aguments和basicProrperties.Headers的所有键值对都相等时才会路由到queue(AND关系);

当x-match为any时,aguments和basicProrperties.Headers的键值对只要有一个相同就可以路由到queue(OR关系)。

 

下面给大家展示两个案例:创建两个队列Allqueue和Anyqueue,其中Allqueue和exchange绑定时的x-match为all,Anyqueue和exchange绑定时的x-match为any;然后发送两条消息。

发送第一条消息时basicProperties.Headers中的user和pass都和绑定队列时的agruments的user和pass相等,发送第二条消息是两者的pass不相等,代码如下图(内容较多,分两张图展示):

 

执行程序,打开WebUI管理界面,结果如下,我们看到只有user和pass都相等时消息才会路由到Allqueue;user和pass只要有一个相等就会路由到Anyqueue,如图

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值