RabbitMq系列(六):交换类型以及例子

系列文章

RabbitMq系列(一):服务器搭建

RabbitMq系列(二):最简单的例子

RabbitMq系列(三):工作队列

RabbitMq系列(四):消息确认和持久性

RabbitMq系列(五):公平派遣

RabbitMq系列(六):交换类型以及例子

RabbitMq系列(七):直接交换Direct exchange

RabbitMq系列(八):扇出交换Fanout Exchange

RabbitMq系列(九):主题交换Topic Exchange

RabbitMq系列(十):标头交换Headers exchange

RabbitMq系列(十一):远程调用RPC

​​​​​

目录

前言

直接交换Direct exchange

例子1

例子2

扇出交换Fanout Exchange

例子1

主题交换Topic Exchange

例子1

例子2

例子3

例子4

标头交换Headers exchange

例子1

例子2


前言

前面对RabbitMq进行应用和熟悉的过程中,我们对交换机( exchange ,官方比作邮局和邮箱,这里以下统称 交换机 )的使用总是一笔带过,对于交换机的作用以及相关信息都不了解,那么交换机是干什么用的呢?路由键( routingKey )和交换机有什么关系?交换机类型有哪些以及它们之间的区别?

生产者( producers,亦称作 发布者 publishers )将消息发送后,消息并不是直接发送到队列 ( queue ),而是发送到RabbitMq代理服务器第一站——交换机。交换机是由虚拟主机( virtual host )定义的消息代理,他一边接受生产者发送的消息,一边通过声明好的路由规则将消息副本分发到相应的队列。然后,要么代理主动将消息推送给订阅了队列的消费者( consumers  ),要么消费者根据自己的需求主动去获取。

路由规则在消息发送过程中是至关重要的一环,在队列通过绑定( binding )动作绑定到交换机上面后,会产生一个类似于 link 的关系,消息来临时,交换机通过路由规则查找相应的队列并将消息发送到队列中。

路由规则主要由消费者和生产者的路由键( routingKey  )、交换机类型( exchange type )来决定的,两个路由键( routingKey )就像是路由规则中的两个关键属性,而交换机类型( exchange type )则决定怎么使用路由键( routingKey  )来产生规则,类似于方法。

其主要工作流程是:

  • 消费者声明的队列(( queue )通过绑定动作绑定到交换机( exchange ) 上面,产生 link 关系和 binding-key ( 这里就是消费者定义的 routingKey )
  • 生产者发布消息后,消息带者生产者定义的 routingKey 到达交换机后,产生一个 routing-key (  这里就是生产者定义的 routingKey ) 
  • 交换机根据交换类型来对 binding-key 和 routing-key 来进行匹配判断,筛选出符合规则的队列将消息发送出去。

交换机类型看起来有五种:

交换类型默认
直接交换 Direct exchangeamq.direct
扇出交换 Fanout exchangeamq.fanout
主题交换  Topic exchangeamq.topic
标头交换  Headers exchangeamq.headers
默认交换 Default exchange空字符串

 

实际上最后一种,默认交换 Default exchange 是特殊的直接交换。其主要是在声明的阶段路由键为空字符串产生。默认交换是由消息服务器帮我们预先声明好的一种特殊的直接交换,队列使用默认交换可以直接产生一个同名的路由键,当有消息到达交换机后,由交换机根据同名的路由键将消息路由给队列。

下面我们针对主要的四种交换类型进行详细描述。

 

直接交换Direct exchange

直接交换是一种依赖于路由键( routing-key )的交换方式,对于单对单发送消息来说,它是最理想的方案,应用这种方案,exchange type 必须定义成直接交换类型。

消息到达交换机过后,交换机会根据 binding-key 和 routing-key 是否完全匹配来决定消息的发送。如果 routing-key 不匹配任意一个  binding-key,消息会被释放。

例子1

  • exchange:exchange.direct
  • queue:queue.direct
  • consumer routingKey :direct.route.*
  • producer routingKey :direct.route.one

direct.route.* 与 direct.route.one不完全匹配,所以当消息到达交换机 ack.exchange 的时候,消息不会被路由到任何队列,消息被释放

例子2

  • exchange: exchange.direct
  • queue:queue.direct
  • consumer routingKey :direct.route.#
  • producer routingKey :direct.route.#

direct.route.# 与 direct.route.# 完全匹配,交换机 exchange.direct 将到达的消息发送到队列 queue.direct

 

扇出交换Fanout Exchange

扇出交换是忽略路由键的交换方式,它不关注路由键,它只关注当前绑定到交换机上面的队列。当消息到达交换机后,交换机会将消息路由到绑定在它上面的所有队列中。

例如当前有5个队列绑定在 ack.exchange 这个交换机上面,并且交换类型都是扇出交换,那么无论路由键怎样,交换机发送消息这5个队列都会收到。

扇出交换是最理想的广播消息模式,对于同一个消息的不同处理、公告更新等,它都是最理想的选择。

例子1

  • exchange:exchange.fanout
  • queue:queue.fanout
  • consumer routingKey :fanout.route.*
  • producer routingKey :fanout.route.one

尽管direct.route.* 与 direct.route.one不完全匹配,但是当前为广播模式,所以忽略路由键。消息到达交换机 exchange.fanout 后会被发送到队列 queue.fanout

 

主题交换Topic Exchange

交换机使用主题交换会在消息到达后,对  binding-key 和 routing-key 进行模糊匹配来决定将消息发送给一个或者多个队列。主题交换就像是扇出交换和直接交换的折中,它主要针对有选择性的处理消息的情况,类似于数据权限的权限筛选。

主题交换除了一般的完全匹配(如: act.direct.route 与 act.direct.route ),还支持 # 和 * 的模糊匹配。

# 代表匹配任意零个或者多个字符

* 代表匹配任意一个字符

主题交换是最灵活的交换方式,所以它适用于很多场景,但是更多的还是特定情况的特殊处理方案的应用。

当消息到达交换机过后,交换机会将消息的  routing-key 来匹配队列 binding-key,这样看起来就跟某字符串匹配正则表达式一样,通过匹配的一个或者多个队列交换机会将消息路由到其中。

例子1

  • exchange:exchange.topic
  • queue:queue.topic
  • consumer routingKey :topic.route.*
  • producer routingKey :topic.route.one

topic.route.one 符合 topic.route.* 的匹配, * 匹配任意字符,这里匹配 one,消息到达交换机 exchange.topic 后,交换机会将消息路由到队列 queue.topic

例子2

  • exchange:exchange.topic
  • queue:queue.topic
  • consumer routingKey :topic.#
  • producer routingKey :topic.route.*

# 匹配零个或者多个字符,这里匹配 route.* ,所以 topic.# 完全匹配 topic.route.*,消息到达交换机 exchange.topic 后,交换机会将消息路由到队列 queue.topic

例子3

  • exchange:exchange.topic
  • queue:queue.topic
  • consumer routingKey :topic.#.cn
  • producer routingKey :topic.cn

# 匹配零个或者多个字符,这里匹配零个字符,所以 topic.#.cn 完全匹配 topic.cn,消息到达交换机 exchange.topic 后,交换机会将消息路由到队列 queue.topic

例子4

  • exchange:exchange.topic
  • queue:queue.topic
  • consumer routingKey :topic.one
  • producer routingKey :topic.#

one 不匹配  # ,one 只能与 one 匹配,所以 topic.one 不匹配 topic.#,消息到达交换机 exchange.topic 后,消息被释放,

匹配的时候,请注意,谁匹配谁

 

标头交换Headers exchange

标头交换是一个忽略路由键的交换模式,类型为 Headers 的交换机在消息到达后,会将消息所带 headers 中 key/value 参数与绑定队列所带 key/value 参数进行比较,基于不同的 x-match 类型不一样的比较规则。

x-match 为 Headers 交换类型中特有的参数,其同样可以作为队列绑定参数,但是,x-match 不作为匹配的参数, x- 开头的参数会被交换机定义为不可匹配参数,需要注意的是,生产者发送消息的时候也能添加 x-match 作为参数,但是交换机进行参数匹配主要是基于消费者的  x-match 

x-match 的value有两个,any 和 all

any 代表匹配参数中的任意一组

all 代表匹配参数中的所有组,x-match除外

key/value 这样才能被称为一组,例如 type = zip

例子1

  • exchange:exchange.header
  • queue:queue.header
  • consumer routingKey :header.#
  • producer routingKey :header.*
  • consumer args:  name=张三,age=32,x-match=all
  • producer headers: name=张三,age=321,x-match=any

因为是 Headers 交换模式,routingKey 在这里无效,所以消息到达后匹配参数,这里看 consumer 的 args 和 producer 的 headers,args 和 headers 都有x-match,那么究竟谁来定规则喃?

队列要不要这个消息当然由定义队列规则的消费者来定,x-match=all,所以这里的规则是匹配除 x-match 外的所有参数,一个age = 32,另一个 age=321,所以匹配失败,消息被释放

例子2

  • exchange:exchange.header
  • queue:queue.header
  • consumer args:  name=zhangsan,age=32,x-match=any
  • producer headers: name=张三,age=32,x-match=all

根据例子1,这里 x-match=any,所以这里的规则是匹配任意一个参数,一个age = 32,另一个也是 age=32,所以匹配成功,消息到达交换机 exchange.header 后,交换机会将消息发送到队列 queue.header

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值