四、RabbitMQ Exchange类型
RabbitMQ整体上是一个生产者与消费者模型,主要负责接收、存储和转发消息。可以把消息传递的过程想象成:当你将一个包裹送到邮局,邮局会暂存并最终将邮件通过邮递员送到收件人的手上,RabbitMQ就好比由邮局、邮箱和邮递员组成的一个系统。从计算机术语层面来说,RabbitMQ模型更像是一种交换机模型。
RabbitMQ模型
(https://img2018.cnblogs.com/blog/1070782/201811/1070782-20181126114829628-838184144.png)
从图中可以看出RabbitMQ主要由Exchange和Queue两部分组成,然后通过RoutingKey关联起来,消息投递到Exchange然后通过Queue接收存储。
消息队列运转过程

生产者将业务方数据进行可能的包装,之后封装成消息,发送(AMQP协议里这个动作对应的命令为
Basic.Publish)到Broker中。消费者订阅并接收消息(AMQP协议里这个动作对应的命令为
Basic.Consume或者Basic.Get),经过可能的解包处理得到原始的数据,之后再进行业务处理逻辑。这个业务逻辑并不一定需要和接收消息的逻辑使用同一个线程。
消费者进程可以使用一个线程去接收消息,存入到内存中,比如
Java中的BlockingQueue。业务处理逻辑使用另一个线程从内存中读取数据,这样可以将应用进一步解耦,提高整个应用的处理效率。
基本概念
在理解Exchange之前,我们先了解RoutingKey、Binging、Queue和Message概念、
RoutingKey:
路由键。生产者将消息发给交换器时,一般指定一个
RoutingKey,用来指定这个消息的路由规则,而这个RoutingKey需要与交换器类型和绑定键(BindingKey)联合使用才能最终生效。在交换器类型和绑定键(BindingKey)固定的情况下,生产者可以在发送消息给交换器时,通过指定
RoutingKey来决定消息流向哪里。Binding:
Exchange与Exchange、Queue之间的虚拟连接,Binding中可以包含Routing key或参数。
便于理解,个人把Binding的Routing key称为Bindingkey(官方没有这种键,只是个人方便理解而加入)。
RabbitMQ中通过Binding将交换器与交换器或队列关联起来,在绑定的时候一般会指定一个BindingKey,这样RabbitMQ就知道如何正确的将消息路由到队列,如图

注意:
default Exchange不能进行Binding,也不需要进行绑定
除default Exchange之外,其他任何Exchange都需要和Queue进行Binding,否则无法进行消息路由(转发)
Binding的时候,可以设置一个或多个参数,其中参数要特别注意参数类型,如果Routing key中指定的参数类型和消息中指定的参数类型不一致(header Exchange)也不能进行消息转发。
Direct Exchange,Topic Exchange进行Binding的时候,发送消息时需要指定Routing key
Fanout Exchange,Headers Exchange进行Binding的时候,发送消息时可以不指定Routing key。
Queue:
队列,保存消息并将它们转发给消费者。
Message
消息。服务器和应用程序之间传送的数据,本质上就是一段数据,由Properties和Payload(body)组成。
**Exchange: **交换器。根据路由键转发消息到绑定的队列。
Exchange在RabbitMQ中的作用:客户端发送消息不会直接发送到队列(Queue)中,而是直接发送给交换器(Exchange),由交换器将消息路由到一个或多个队列中。
RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储。
RabbitMQ提供了四种Exchange:fanout,direct,topic,header。但常用的主要是fanout,direct,topic。
性能排序:fanout > direct >> topic。比例大约为11:10:6。
direct
把消息路由到与
BindingKey和RoutingKey完全相等的队列中。- 一个Exchange可以Binding一个或多个Queue
- 绑定可以指定RoutingKey,Binding的多个Queue可以使用相同的BindingKey,也可以使用不同的BindingKey
如下图,在该类型下指定
RoutingKey为warming,Exchange和Queue1、Queue2的BindingKey都有warming,所以消息都会路由到Queue1和Queue2。
如果指定
RoutingKey为info,而Exchange有BindingKey为info的只有Queue2,所以消息只能路由到Queue2。注意:
默认的Exchange(名字为空,显示为
(AMQP default))- 默认的Exchange不能进行Binding操作
- 任何发送到该Exchange的消息都会被转发到Routing key指定的Queue中
- 如果vhost中不存在Routing Key中指定的队列名,则该消息会被抛弃
topic
个人把Binding的Routing key称为Bindingkey(官方没有这种键,只是个人方便理解而加入)。
与
direct类型的交换器路由规则BindingKey和RoutingKey完全相等不同,将消息中的Routing key与该Exchange关联的BindingKey进行对比,如果匹配上了,则发送到该Binding对应的Queue中。匹配规则
*匹配一个单词
#匹配0个或多个字符
*,#只能写在.号左右,且不能挨着字符
单词和单词之间需要.隔开。例子
BindingKey是
user.log.#,因为#是匹配0个或多个字符,所以下面RoutingKey的可以匹配:user.log
user.log.info
user.log.a
user.log.info.login
BindingKey是
user.log.*,因为*匹配一个单词,所以user.log.info 可以匹配
user.log 不能匹配
user.log.info.login 不能匹配,二个单词
BindingKey是
#.log.#, 可以匹配:log
user.log
log.info
user.log.info
user.log.info.a
BindingKey是
*.log.*log 不匹配
user.log 不匹配
log.info 不匹配
user.log.info 匹配,前后各一个单词
user.log.info.a 不匹配
a.user.log.info 不匹配
BindingKey是
*.action.#action 不符合
action.log 不符合
user.action.log 符合
user.action.log.info 符合
user.action 符合
user.log.action 不符合
BindingKey是
#.action.*action 不符合
user.action 不符合
user.action.action 符合
user.action.login 符合
user.action.login.count 不符合
BindingKey是
*表示匹配一个单词BindingKey是
#,或者#.#表示匹配所有
如果指定了Exchange是Topic类型的,但是相应的
BindingKey中只有单词,*和#都没有,则相等才转发,类似于Direct Exchange。
如果BindingKey为#或者#.#,则全部转发,类似Fanout Exchange(下面会讲到)如下图
RoutingKey为"com.rabbitmq.client"的消息会同时路由到Queue1和Queue2;RoutingKey为"com.hidden.client"的消息只会路由到Queue2中;RoutingKey为"com.hidden.demo"的消息只会路由到Queue2中;RoutingKey为"java.rabbitmq.demo"的消息只会路由到Queue1中;RoutingKey为"java.util.concurrent"的消息将会被丢弃或返回给生产者(需要设置mandatory参数),因为没有匹配任何路由键

fanout
直接将消息转发到所有
binding的对应queue中,这种exchange在路由转发的时候,忽略Routing key。Fanout Exchange
这种exchange效率最高,fanout > direct > topic定义一个Fanout类型的Exchange,绑定了一些队列,发送的时候全部队列都能收到消息,而与其bind或者发送消息指定的Routing key无关。
headers
将消息中的
headers与该Exchange相关联的所有Binging中的参数进行匹配,如果匹配上了,则发送到该Binding对应的Queue中。headers类型的交换器的性能比较差,少用。匹配规则:
如果Binding中的
x-match = all:表示所有的键值对都匹配才能转发到消息。
x-match = any: 表示只要有键值对匹配就能转发消息。注意:
Binging的时候,至少需要指定两个参数,其中的一个是x-match = all或x-match = any。Binging的时候,不需要指定Routing key- 发送消息的时候,不需要指定
Routing key - 转发消息的时候,忽略
Routing key - 如果是
x-match = all则发送的headers不能比bingding的参数少,否则匹配不上。
四、RabbitMQ Exchange类型的更多相关文章
- RabbitMQ Exchange类型详解
前言 在上一篇文章中,我们知道了RabbitMQ的消息流程如下: 但在具体的使用中,我们还需知道exchange的类型,因为不同的类型对应不同的队列和路由规则. 在rabbitmq中,exchange ...
- RabbitMQ四种交换机类型介绍
RabbitMQ 原文地址: https://baijiahao.baidu.com/s?id=1577456875919174629&wfr=spider&for=pc 最新版本的 ...
- RabbitMQ 四种Exchange
AMQP协议中的核心思想就是生产者和消费者隔离,生产者从不直接将消息发送给队列.生产者通常不知道是否一个消息会被发送到队列中,只是将消息发送到一个交换机.先由Exchange来接收,然后Exchang ...
- 快速掌握RabbitMQ(二)——四种Exchange介绍及代码演示
在上一篇的最后,编写了一个C#驱动RabbitMQ的简单栗子,了解了C#驱动RabbitMQ的基本用法.本章介绍RabbitMQ的四种Exchange及各种Exchange的使用场景. 1 direc ...
- RabbitMQ路由类型
关于RabbitMQ的Exchange类型 参考地址:<RabbitMQ学习系列(四): 几种Exchange 模式> github地址:https://github.com/ChenWe ...
- rabbitmq exchange type
This is the fourth installment to the series: RabbitMQ for Windows. In thelast installment, we revi ...
- 5、RabbitMQ - Exchange之 fanout \ 【direct 关键字发送】 \ topic
pytho系列之 RabbitMQ - Exchange几种模式 RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 Rab ...
- MySQL表的四种分区类型
MySQL表的四种分区类型 一.什么是表分区 通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysql5.1开始支持数据表分区了. 如:某用户表的记录超过了600万条,那么就可以根据入库日期将表 ...
- C++中四种转换类型的区别
一.四种转换类型比较: 类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可 ...
随机推荐
- Try setting a different JdbcType for this parameter or a different configuration property. Cause: org.postgresql.util.PSQLException: 栏位索引超过许可范围:2,栏位数:1
执行mybaits sql <delete id="delete4BatchesByLineCi" parameterType="java.util.List&qu ...
- MySQL--InnoDB 体系架构
InnoDB 体系架构 后台线程 Master Thread Master Thread 是一个非常核心的后台线程,主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性,包括脏页的刷新.合并插入缓 ...
- openlayers的loaders方式加载
openlayers loaders方式加载 let layerVector = new ol.layer.Vector({ source : new ol.source.Vector({ loade ...
- CSS3 media媒体查询器的使用方法
最近几年随着响应式布局的发展,一次开发多次使用,自适应屏幕的响应式网站的需求越来越多.但是怎样使得网站能自适应屏幕呢?这里就需要提到一个css3里面新增的技术了-media媒体查询器. 那么什么是me ...
- IDA解析so文件异常(Binary data is incorrect maximum possible value is xx)
错误信息 Binary data is incorrect maximum possible value is 0 错误原因 so文件损坏 或者ida换成32 解决办法 重新获得so文件,或者调整id ...
- 什么?你还没女朋友?教你如何借助Python俘获女孩子芳心!
天气降温,感情却升温了? 上午刚到公司,就收到小Q发来的灵魂拷问: “Q仔!要不然下午请个假!我带你去精神科看看!?”我实在忍不了,脱口而出. 话音未落,前排的运营小花回头看向小Q,莞尔一笑,百媚横生 ...
- Ambiguous HTTP method Actions require an explicit HttpMethod binding for Swagger 2.0 异常
网上看了很多关于此异常的解决方案,但是大多数都是不能用的,今天把正确的解决方案记录下来,以帮助需要的人 问题:有些接口没有设置HttpPost或HttpGet,非接口设置访问权限为private,控制 ...
- 【MySQL参数】-innodb_flush_method
innodb_flush_method这个参数控制着innodb数据文件及redo log的打开.刷写模式,对于这个参数,文档上是这样描述的:有三个值:fdatasync(默认),O_DSYNC,O_ ...
- mongodb的常见使用命令行
由于cms工程要连接mongodb所以需要在在cms服务端工程添加如下依赖:项目使用spring data mongodb操作mongodb数据库 <dependency> <gro ...
- ZJNU 2204 - dzj的数学作业
我猜这个数列可以直接从大到小凑…… 推出帕多瓦数列每一项,从大到小循环 遇到小于等于x的项就减掉这一项 全部循环完毕后判断x是否为0即可 #include<stdio.h> typedef ...