RabbitMQ整体上是一个生产者与消费者模型,主要负责接收、存储和转发消息。可以把消息传递的过程想象成:当你将一个包裹送到邮局,邮局会暂存并最终将邮件通过邮递员送到收件人的手上,RabbitMQ就好比由邮局、邮箱和邮递员组成的一个系统。从计算机术语层面来说,RabbitMQ模型更像是一种交换机模型。

RabbitMQ模型

(https://img2018.cnblogs.com/blog/1070782/201811/1070782-20181126114829628-838184144.png)

从图中可以看出RabbitMQ主要由ExchangeQueue两部分组成,然后通过RoutingKey关联起来,消息投递到Exchange然后通过Queue接收存储。

消息队列运转过程

  1. 生产者将业务方数据进行可能的包装,之后封装成消息,发送(AMQP协议里这个动作对应的命令为Basic.Publish)到Broker中。

  2. 消费者订阅并接收消息(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: **交换器。根据路由键转发消息到绑定的队列。

ExchangeRabbitMQ中的作用:客户端发送消息不会直接发送到队列(Queue)中,而是直接发送给交换器(Exchange),由交换器将消息路由到一个或多个队列中。

RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储。

RabbitMQ提供了四种Exchange:fanout,direct,topic,header。但常用的主要是fanout,direct,topic。

性能排序:fanout > direct >> topic。比例大约为11:10:6。

  1. direct

    把消息路由到与BindingKeyRoutingKey完全相等的队列中。

    1. 一个Exchange可以Binding一个或多个Queue
    2. 绑定可以指定RoutingKey,Binding的多个Queue可以使用相同的BindingKey,也可以使用不同的BindingKey

    如下图,在该类型下指定RoutingKeywarmingExchangeQueue1Queue2BindingKey都有warming,所以消息都会路由到Queue1Queue2

    如果指定RoutingKeyinfo,而ExchangeBindingKeyinfo的只有Queue2,所以消息只能路由到Queue2

    注意:

    默认的Exchange(名字为空,显示为(AMQP default)

    1. 默认的Exchange不能进行Binding操作
    2. 任何发送到该Exchange的消息都会被转发到Routing key指定的Queue中
    3. 如果vhost中不存在Routing Key中指定的队列名,则该消息会被抛弃
  2. topic

    个人把Binding的Routing key称为Bindingkey(官方没有这种键,只是个人方便理解而加入)。

    direct类型的交换器路由规则BindingKeyRoutingKey完全相等不同,将消息中的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"的消息会同时路由到Queue1Queue2;
    • RoutingKey"com.hidden.client"的消息只会路由到Queue2中;
    • RoutingKey"com.hidden.demo"的消息只会路由到Queue2中;
    • RoutingKey"java.rabbitmq.demo"的消息只会路由到Queue1中;
    • RoutingKey"java.util.concurrent"的消息将会被丢弃或返回给生产者(需要设置mandatory参数),因为没有匹配任何路由键

  1. fanout

    直接将消息转发到所有binding的对应queue中,这种exchange在路由转发的时候,忽略Routing key

    Fanout Exchange这种exchange效率最高,fanout > direct > topic

    定义一个Fanout类型的Exchange,绑定了一些队列,发送的时候全部队列都能收到消息,而与其bind或者发送消息指定的Routing key无关。

  2. headers

    将消息中的headers与该Exchange相关联的所有Binging中的参数进行匹配,如果匹配上了,则发送到该Binding对应的Queue中。

    headers类型的交换器的性能比较差,少用。

    匹配规则:

    如果Binding中的

    x-match = all:表示所有的键值对都匹配才能转发到消息。

    x-match = any: 表示只要有键值对匹配就能转发消息。

    注意:

    1. Binging的时候,至少需要指定两个参数,其中的一个是x-match = allx-match = any
    2. Binging的时候,不需要指定Routing key
    3. 发送消息的时候,不需要指定Routing key
    4. 转发消息的时候,忽略Routing key
    5. 如果是x-match = all则发送的headers不能比bingding的参数少,否则匹配不上。

四、RabbitMQ Exchange类型的更多相关文章

  1. RabbitMQ Exchange类型详解

    前言 在上一篇文章中,我们知道了RabbitMQ的消息流程如下: 但在具体的使用中,我们还需知道exchange的类型,因为不同的类型对应不同的队列和路由规则. 在rabbitmq中,exchange ...

  2. RabbitMQ四种交换机类型介绍

    RabbitMQ  原文地址: https://baijiahao.baidu.com/s?id=1577456875919174629&wfr=spider&for=pc 最新版本的 ...

  3. RabbitMQ 四种Exchange

    AMQP协议中的核心思想就是生产者和消费者隔离,生产者从不直接将消息发送给队列.生产者通常不知道是否一个消息会被发送到队列中,只是将消息发送到一个交换机.先由Exchange来接收,然后Exchang ...

  4. 快速掌握RabbitMQ(二)——四种Exchange介绍及代码演示

    在上一篇的最后,编写了一个C#驱动RabbitMQ的简单栗子,了解了C#驱动RabbitMQ的基本用法.本章介绍RabbitMQ的四种Exchange及各种Exchange的使用场景. 1 direc ...

  5. RabbitMQ路由类型

    关于RabbitMQ的Exchange类型 参考地址:<RabbitMQ学习系列(四): 几种Exchange 模式> github地址:https://github.com/ChenWe ...

  6. rabbitmq exchange type

    This is the fourth installment to the series: RabbitMQ for Windows.  In thelast installment, we revi ...

  7. 5、RabbitMQ - Exchange之 fanout \ 【direct 关键字发送】 \ topic

    pytho系列之 RabbitMQ - Exchange几种模式 RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 Rab ...

  8. MySQL表的四种分区类型

    MySQL表的四种分区类型 一.什么是表分区 通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysql5.1开始支持数据表分区了. 如:某用户表的记录超过了600万条,那么就可以根据入库日期将表 ...

  9. C++中四种转换类型的区别

    一.四种转换类型比较: 类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可 ...

随机推荐

  1. Linux-socket编程接口介绍

    1.建立连接 (1).socket.socket函数类似于open,用来打开一个网络连接,如果打开成功则返回一个网络文件描述符(int类型),之后我们操作这个网络连接都可以通过这个网络文件描述符. ( ...

  2. idea指定启动参数、环境变量

    1.  点击Edit Configurations 2 # VM Arguments 是设置的虚拟机的属性 # VM options # 环境变量参数 这里需要指定-D参数 -server -XX:M ...

  3. 用Pandas Dataframe来抓取重构金融股票的各种业务&数据形态

    4. 如果计算各项股票指标时,或者处理业务流程时,上一篇的直观认知数据结构,怎样帮助开发者去好好操作,又同时避免计算错误的坑. 首先从上篇的数据结据,可以看出/设计出多少种业务和股票指标. A. 恒生 ...

  4. shell 命令综合实战

    此篇为运维人员(开发)经常使用的查看系统状态的相关命令,主要综合了awk,grep ,sed等文本处理命令,能够大大提高工作效率,在此做个简单分享,也便于自己以后查找,毕竟好记性不如烂笔头. 获取et ...

  5. matlab画图中的坐标轴设置

    ax = gca; ax是个结构体,查看ax变量,可以看到所有可设置的属性.几个常见属性如下: 设置坐标轴字体大小,粗细,字体名 2014b之后版本: ax = gca; ax.FontSize = ...

  6. 68)deque数组

    基本要求: 1)和vecctor基本区别   示意图 vector在尾部添加和删除, deque在尾部添加和删除,在头部添加和删除. 2)基本知识: 3)deque的构造形式:   4)基本操作和遍历 ...

  7. 个性化bash

    zsh/on-my-zsh Ubuntu,deepin, 等可以使用  apt install 的系统  apt install zsh 一般就可以自动安装 RedHat(Fedora,Centos) ...

  8. endnote插入|管理文件|成组

    信息检索 Endnote Filter(导入)---library(管理)---style(导出) 本地+网络数据库 点击research 在WOS上: 导入改文献: CNKI 导入PDF时选择PDF ...

  9. ZJNU 1426 - YNingC的困惑

    注意到N最大只有1e6,但是xy最大有2e8,直接模拟2e8会超时 所以可以将1e6个区间离散化后模拟,模拟时的最坏情况为2e6满足题意 /* Written By StelaYuri */ #inc ...

  10. 论文:利用深度强化学习模型定位新物体(VISUAL SEMANTIC NAVIGATION USING SCENE PRIORS)

    这是一篇被ICLR 2019 接收的论文.论文讨论了如何利用场景先验知识 (scene priors)来定位一个新场景(novel scene)中未曾见过的物体(unseen objects).举例来 ...