7.Exchange交换机
Exchang:用来接收消息,并且根据路由键转发消息所绑定的队列的,我们来看下官网的这张图
在这张图中描述了这样的几个部分
蓝色区域:表示消息的发送要经过的处理,在上一节我们看到生产者将消息投递到Queue中,实际上这在RabbitMQ中这种事情永远都不会发生。实际的情况是,生产者将消息发送到Exchange(交换器),由Exchange将消息路由到一个或多个Queue中(或者丢弃)。
绿色区域:消息接受者(消费者)从队列中获取消息
红色区域:表示rabbitmq server中工作的一些组件
黄色区域:指Exchange通过RoutingKey和Queue绑定在一起
交换机的属性
Name:交换机名字
Type:交换机类型 direct、topic、fanout、headers
Durability:是否需要持久化,true为持久化
Auto Delete:当最后一个绑定到Exchange上的队列删除后,自动删除该Exchange
Arguments:扩展参数,用于扩展AMQP协议自制定化使用
Internal:当前Exchange是否用于RabbitMQ内部使用,默认false,一般熟悉erlang自己扩展插件才会用到
接下来来详细讲下这几种模式
1.Direct Exchange
所有发送到Direct Exchange的消息被转发到RouteKey中制定的Queue,Direct模式可以使用RabbitMQ自带的Exchange:default Exchange,所以不需要将Exchange进行任何的绑定操作,消息传递时,Routekey必须完全匹配才会被队列接收,否则该消息会被抛弃
以上图的配置为例,我们以routingKey=”error”发送消息到Exchange,则消息会路由到Queue1(amqp.gen-S9b…,这是由RabbitMQ自动生成的Queue名称)和Queue2(amqp.gen-Agl…);如果我们以routingKey=”info”或routingKey=”warning”来发送消息,则消息只会路由到Queue2。如果我们以其他routingKey发送消息,则消息不会路由到这两个Queue中。
看下生产者和消费者的代码,连接和关闭等代码不变,我们看下核心的变化
生产者
1 | /** |
消费者
通过这个案例中,我们可以看出direct这种直连模式,通过指定的routingKey去访问对应的交换机中的队列
2.Topic Exchange
前面讲到direct类型的Exchange路由规则是完全匹配binding key与routing key,但这种严格的匹配方式在很多情况下不能满足实际业务需求。topic类型的Exchange在匹配规则上进行了扩展,它与direct类型的Exchage相似,也是将消息路由到binding key与routing key相匹配的Queue中,但这里的匹配规则有些不同,
topic是一种模糊匹配,它约定:
routing key为一个句点号“. ”分隔的字符串(我们将被句点号“. ”分隔开的每一段独立的字符串称为一个单词),如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit”
binding key与routing key一样也是句点号“. ”分隔的字符串。
binding key中可以存在两种特殊字符“”与“#”,用于做模糊匹配,其中“”用于匹配一个单词,“#”用于匹配多个单词(可以是零个)。
以上图中的配置为例,routingKey=”quick.orange.rabbit”的消息会同时路由到Q1与Q2,routingKey=”lazy.orange.fox”的消息会路由到Q1与Q2,routingKey=”lazy.brown.fox”的消息会路由到Q2,routingKey=”lazy.pink.rabbit”的消息会路由到Q2(只会投递给Q2一次,虽然这个routingKey与Q2的两个bindingKey都匹配);routingKey=”quick.brown.fox”、routingKey=”orange”、routingKey=”quick.orange.male.rabbit”的消息将会被丢弃,因为它们没有匹配任何bindingKey。
生产者
消费者
3.fanout
fanout类型的Exchange路由规则非常简单,它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中。也就是完全忽略routingKey
上图中,生产者(P)发送到Exchange(X)的所有消息都会路由到图中的两个Queue,并最终被两个消费者(C1与C2)消费。
我们只需要在消费者中不指定routingKey,生产者也不主要关注routingKey,只需要关注交换机就好了
生产者
消费者
4.headers
headers类型的Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。
在绑定Queue与Exchange时指定一组键值对;当消息发送到Exchange时,RabbitMQ会取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配Queue与Exchange绑定时指定的键值对;如果完全匹配则消息会路由到该Queue,否则不会路由到该Queue。
该类型的Exchange没有用到过(不过也应该很有用武之地),所以不做介绍。