前言

 

  RabbitMQ是消息队列中间件(Message Queue Middleware)中一种,工作虽然有用到,但是却没有形成很好的整体包括,主要是一些基础概念的认识,这里通过阅读《RabbitMQ实战指南》整理笔记并进行代码实践,更好地理解RabbitMQ!

本文只通过讲解RabbitMQ的一些基础概念,主要是RabbitMQ的“生产者-消费者”模型涉及到的交换器、路由键、绑定键、消息路由规则等,下一篇RabbitMQ是如何运转的?会有简单介绍RabbitMQ的运转、RabbitMQ部署,Java代码实践。

  需要电子书PDF版《RabbitMQ实战指南》(高清带标签)可以评论或者联系我


一、MQ的作用

  讲解RabbitMQ之前先认识下MQ作为消息中间件的作用(优点),使用的时候如果不去思考为什么用MQ,怎样更好地才能达到它的作用的话,那都是毫无意义的使用!

    1、解耦:可以很好地屏蔽应用程序及平台之间的特性,充当中间者,松散耦合应用程序及平台,它们彼此不需要了解远程过程调用RPC与网络协议的细节;

  2、异步通信:能提供C/S之间同步与异步连接,在任何时刻都可以将消息进行传送或者存储转发;

    3、可恢复性:当消息接收方宕机或网络不通的情况下,消息转储于MQ中,直到网络恢复或接收方恢复再进行转发;

  4、扩展性:提高消息入队列和处理效率是容易的,只需要另外增加处理过程即可,不需要改变代码,也不需要调节参数。

  5、顺序性:由于大部分MQ支持队列模式,自然也就能保证一定的数据处理顺序(事实上是不准确的,很有局限性。消息的顺序性取决于很多因素)

  6、缓冲:MQ通过一个缓冲层来帮助任务最高效率执行,写入MQ的处理会尽可能快速。

二、RabbitMQ的“交换机”模型

  RabbitMQ整体的模型其实是一种“生产者-消费者”模型,发送消息的一方称之为生产者,接收消息一方称之为消费者。中间会有交换器、队列、Broker等概念。下图是简单的RabbitMQ的模型图(截图来自于《RabbitMQ实战指南》,以下截图同)

          

      

  1、生产者-消费者与RabbitMQ Broker 

    (1)Producer:

      投递消息的一方,创建了消息之后发布到RabbitMQ中,消息主要包括消息体(Payload)与Label标签,消息体可以通常是业务数据,比如JSON等,Label则用来表述这条消息,比如一个交换机名称和一个路由键。

生产者把消息交由RabbitMQ,之后会根据标签把消息发送给感兴趣的消费者。

    (2 Consumer:

      消费者,接收消息的一方,连接到RabbitMQ服务器,并订阅到队列上,当消费者消费一条消息时只是消费了消息体payload,在消息路由过程中,消息的标签会丢失,存入队列中只有消息体。消费者不需要知道生产者是谁。

    (3)Broker:

      消息中间件的服务节点,一个RabbitMQ Broker可以简单地看做一个RabbitMQ服务节或者RabbitMQ服务实例(大多数情况下可以看做是一台RabbitMQ的服务器

    由上图可知,消息队列运转过程是这样的:

    封装好的消息发送(AMQP命令为Basic.publish)到Broker中,消费者订阅并接收(Basic.Get/Basic.Consume)消息,之后再进行业务逻辑处理(可以再开另外的进程,不需要与接收消息同一个进程)

            

   2、队列

       RabbitMQ中消息都只能存储在队列中,当多个消费者订阅一个队列时,队列中的消息会被平均分摊(Round-Robin),也就是并不是每个消费者都能收到所有的消息并处理。

                

      注意以下几点:

        1)对于生产者生产的消息到队列中,并不是平均分摊。而是通过路由键、绑定键、交换器类型三个决定消息最终被哪个消费者消费,之后会介绍!

        2)生产者与消费者之间的连接,并不只是通过队列那么简单连接,而是外加通过TCP连接与信道Channel,之后也会介绍

   3、交换器、路由键、绑定   

        (1) 交换器(Exchange, X):由上图交换机模型图中看不到交换器这个东西,但实际上是存在的,生产者将消息投递到队列,然而真实情况是:生产者将消息发送到Exchange,由Exchange再路由到一个或多个队列中;

           交换器的类型有fanout、direct、topic、headers这四种类型,不同的类型的交换器有其独特的匹配规则,这里的匹配规则其实就是决定消息最终路由到哪的队列的关键,具体请往下看

                  

        (2) 路由键(RoutingKey):生产者将消息发送给交换器的时候,会指定RoutingKey指定路由规则,实际情况是需要将RoutingKey、交换器类型、绑定键联合使用才能最终生效。当交换器类型与BindingKey固定情况下,通过执行RoutingKey来决定消息流向哪里。

        (3)绑定(BindingKey):通过绑定键将交换器与队列关联起来,这样RabbitMQ就知道如何正确地将消息路由到队列,其实绑定键也是一种路由键的一种,不过是用在绑定交换器与队列的时候。

                

      总结有以下三点:

       (1) 生产者将消息发送给哪个Exchange是需要由RoutingKey决定的,生产者需要将Exchange与哪个队列绑定时需要由BindingKey决定的(当然还要看交换器类型,BindingKey不一定会生效,如fanout类型交换器);

         (2) 生产者将消息发送给交换器时,需要一个RoutingKey,当BindingKey和RoutingKey相匹配时,消息会被路由到对象的队列中(当然也要看交换器类型)。

         (3)  BindingKey其实也属于路由键的一种,在使用邦定的时候,需要的路由键是BingdingKey,在发送消息的时,需要的路由键是RoutingKey

   4、交换器类型

     为什么非要介绍交换器类型呢?上文中也提到过交换器类型关系到具体的消息路由途径,处路由键、绑定键之外的还需要关注交换器的类型。不同的交换器会有不同的匹配规则。

     RabbitMQ常用的交换器类型有fanout、direct、topic、headers这四种类型

    (1)fanout它会把所有的交换器上的消息路由到所有与该交换器邦定的队列中,不需要BindingKey生效

    (2)direct:它会把消息路由到BindingKey与RoutingKey完全匹配的队列中。比如在发送消息的时候,设置Label中RoutingKey为warning,则消息会路由到Queue1与Queue2上(请看下图)。

                

  

     (3)topic:是direct上的扩展,同样是利用RoutingKey与BindingKey相匹配,但是匹配规则不一样,支持模糊匹配。有如下的规则

      • RoutingKey为一个点号“.”分隔的字符串,每个被隔开的独立字符串即为一个单词,是匹配的单位;
      • BindingKey和RoutingKey一样,也是"."分割的字符串;
      • 但不同的是BindingKey,可以用“#”,“*”进行类似于占位符的模糊匹配,“#”表示一个单词,"*"表示多个单词(也可以是零个)                 

       比如:

        RoutingKey为com.hidden.client的消息只会到队列Queue2中:因为只有Queue2的BindingKey=*.*.client匹配com.hidden.client

        RoutingKey为com.rabbitmq.client的消息会到队列Queue1-2中: 因为Queue1的BindingKey=*.rabbitmq.*.匹配com.rabbitmq.client,Queue2的BindingKey=*.*.client匹配com.rabbitmq.client

        RoutingKey为java.rabbitmq.demo的消息只会到队列Queue1中:因为只有Queue1的BindingKey=*.rabbitmq.*.匹配java.rabbitmq.demo

        RoutingKey为java.util.concurrent的消息会被丢弃或者返回给生产者(需要设置)

                

        (4)headers:依赖发送消息内容中的hearders属性进行匹配,在绑定队列和交换器时指定一组键值对,这里的也就是headers,当发送消息到交换器时,RabbitMQ会获取到该消息的headers,通过比较会路由到相关队列中,这种交换器性能会很差,一般不会使用。


        

     以上内容总结起来只是介绍了RabbitMQ的从生产者产生消息到消费者消费消息过程中涉及到的概念。还未介绍具体的RabbitMQ是如何运转的,比如生产者是怎样建立连接生成消息的,消费者又是怎样读取消息的,这将是下一篇RabbitMQ是如何运转的?主要介绍的。

认识RabbitMQ交换机模型的更多相关文章

  1. 【python】-- RabbitMQ RPC模型

    RabbitMQ RPC模型 RPC(remote procedure call)模型说通俗一点就是客户端发一个请求给远程服务端,让它去执行,然后服务端端再把执行的结果再返回给客户端. 1.服务端 i ...

  2. RabbitMQ消息模型概览(简明教程)

    小菜最近用到RabbitMQ,由于之前了解过其他消息中间件,算是有些基础,所以随手从网上搜了几篇文章,准备大概了解下RabbitMQ的消息模型,没想到网上文章千篇一律,写一大堆内容,就是说不明白到底怎 ...

  3. 1.RabbitMQ工作模型与基本原理

        1.了解 MQ 的本质和 RabbitMQ 的特性: 2.掌握 RabbitMQ 的 Java API 编程和 Spring 集成 RabbitMQ 1. MQ 了解 1.1. 消息队列简介 ...

  4. 关于RabbitMQ交换机的理解

    RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性.扩展性.高可用性等方面表现不俗.消息中间件主要用于组件之间的解耦,消 ...

  5. RabbitMQ交换机规则实例

    RabbitMQ Exchange分发消息时根据类型的不同分发策略有区别,目前共四种类型:direct.fanout.topic.headers .headers 匹配 AMQP 消息的 header ...

  6. RabbitMQ交换机、RabbitMQ整合springCloud

    目标 1.交换机 2.RabbitMQ整合springCloud 交换机 蓝色区域===生产者 红色区域===Server:又称Broker,接受客户端的连接,实现AMQP实体服务 绿色区域===消费 ...

  7. Rabbitmq交换机三种模式介绍

    1.topic 将路由键和某模式进行匹配.此时队列需要绑定要一个模式上.符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词.因此“abc.#”能够匹配到“abc.def.ghi”,但是“abc. ...

  8. 使用代码创建rabbitmq交换机和队列绑定

    1.获取channel对象 2.声明(创建)对列 // 第一个参数,queueName:对列名称.数据类型:String// 第二个参数,durable:是否持久化, 队列的声明默认是存放到内存中的, ...

  9. 【RabbitMQ-7】RabbitMQ—交换机标识符

    死信队列概念 死信队列(Dead Letter Exchange),死信交换器.当业务队列中的消息被拒绝或者过期或者超过队列的最大长度时,消息会被丢弃,但若是配置了死信队列,那么消息可以被重新发布到另 ...

随机推荐

  1. Tensor类型

    Tensor类型 1.Tensor有不同的数据类型,每种类型又有CPU和GPU两种版本: 2.默认的tensor类型是FloatTensor,t.set_default_tensor_type可以修改 ...

  2. python学习:元组和嵌套

    tuple(元组):只是可读,不可以修改# tup1 = () #空元组# tup2 = (20,) #元组内有一个元素,需要在元素后添加逗号 a = (1,2,3,4)print(a[1])a[1] ...

  3. php获取当前时间的毫秒数

    floor(microtime()*1000); 用microtime能输出当前的秒的后面8位小数 乘以1000取整数就行了

  4. NOIP-比例简化

    题目描述 在社交媒体上,经常会看到针对某一个观点同意与否的民意调查以及结果.例如,对某一观点表示支持的有 1498 人,反对的有 902 人,那么赞同与反对的比例可以简单的记为 1498:902 . ...

  5. 记一次Dynamic Batching不生效的爬坑实例分析[Unity]

    最近在项目开发过程中,无意发现游戏场景的绘制占用了大量的Batches,几乎一个模型显示就占用了一个Batch,而Saved by batching数量几乎为0,即没有任何合批渲染优化.这显然跟预期相 ...

  6. 可道云kodexplorer网盘未清理造成linux服务器爆满的解决方法

    今天登陆宝塔面板的时候发现硬盘占用37GB,已经变红提示我空间不足了,惊呆了, 还以为是宝塔抽风了,去远程连接服务器看了一下,懵逼了. df -h 查看挂载目录使用情况 还是不相信现实的我又重启了一下 ...

  7. f12 headers 变字典快捷方式

  8. spring的配置和使用

    spring的配置和使用 1. 创建基于java的配置. 配置极少量的XML来启用java配置:   <?xml version="1.0" encoding="U ...

  9. 2018申请淘宝客AppKey

    1.www.alimama.com 申请账号进入后2.进入我的联盟,按下面的步骤 完成以后等待网站审核. 3.审核完成后 按以下的图,申请进入开放平台或得appkey 4.最后就可以进入开放平台申请看 ...

  10. muse-ui底部导航自定义图标和字体颜色

    最近在鼓捣用vue.js进行混合APP开发,遍寻许久终于找到muse-ui这款支持vue的轻量级UI框架,竟还支持按需引入,甚合萝卜意! 底部导航的点击波纹特效也是让我无比惊喜,然而自定义图标和字体颜 ...