场景模拟

在介绍RabbitMQ之前,我们先来看下面一个电商项目的场景:

  • 商品的原始数据保存在数据库中,增删改查都在数据库中完成。
  • 搜索服务数据来源是索引库(Elasticsearch),如果数据库商品发生变化,索引库数据不能及时更新。
  • 商品详情做了页面静态化处理,静态页面数据也不会随着数据库商品更新而变化。

如果我们在后台修改了商品的价格,搜索页面和商品详情页显示的依然是旧的价格,这样显然不对。该如何解决?

我们可能会想到这么做:

  • 方案1:每当后台对商品做增删改操作,同时修改索引库数据及更新静态页面。
  • 方案2:搜索服务和商品页面静态化服务对外提供操作接口,后台在商品增删改后,调用接口。

这两种方案都有个严重的问题:就是代码耦合,后台服务中需要嵌入搜索和商品页面服务,违背了微服务的独立原则。

这时,我们就会采用另外一种解决办法,那就是消息队列

商品服务对商品增删改以后,无需去操作索引库和静态页面,只需向MQ发送一条消息(比如包含商品id的消息),也不关心消息被谁接收。 搜索服务和静态页面服务监听MQ,接收消息,然后分别去处理索引库和静态页面(根据商品id去更新索引库和商品详情静态页面)。

一、RabbitMQ 工作原理

RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、 安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。RabbitMQ是一个消息代理:它接受和转发消息。 你可以把它想象成一个邮局:当你把邮件放在邮箱里时,你可以确定邮差先生最终会把邮件发送给你的收件人。 在这个比喻中,RabbitMQ是邮政信箱,邮局和邮递员。
RabbitMQ与邮局的主要区别是它不处理纸张,而是接受,存储和转发数据消息的二进制数据块。

1.什么是消息队列

MQ全称为Message Queue,即消息队列。

消息队列(MQ)是一种应用程序对应用程序的通信方法。
应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。
消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。
排队指的是应用程序通过 队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。“消息队列”是在消息的传输过程中保存消息的容器。它是典型的:生产者、消费者模型。生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,这样就实现了生产者和消费者的解耦。

2.模型架构

组成部分说明:

  • Channel(信道):多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内的虚拟连接,复用TCP连接的通道。
  • Producer(消息的生产者):向消息队列发布消息的客户端应用程序。
  • Consumer(消息的消费者):从消息队列取得消息的客户端应用程序。
  • Message(消息):消息由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(消息优先权)、delivery-mode(是否持久性存储)等。
  • Routing Key(路由键):消息头的一个属性,用于标记消息的路由规则,决定了交换机的转发路径。最大长度255 字节。
  • Queue(消息队列):存储消息的一种数据结构,用来保存消息,直到消息发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将消息取走。需要注意,当多个消费者订阅同一个Queue,这时Queue中的消息会被平均分摊给多个消费者进行处理,而不是每个消费者都收到所有的消息并处理,每一条消息只能被一个订阅者接收。
  • Exchange(交换器|路由器):提供Producer到Queue之间的匹配,接收生产者发送的消息并将这些消息按照路由规则转发到消息队列。交换器用于转发消息,它不会存储消息 ,如果没有 Queue绑定到 Exchange 的话,它会直接丢弃掉 Producer 发送过来的消息。交换器有四种消息调度策略(下面会介绍),分别是fanout, direct, topic, headers。
  • Binding(绑定):用于建立Exchange和Queue之间的关联。一个绑定就是基于Binding Key将Exchange和Queue连接起来的路由规则,所以可以将交换器理解成一个由Binding构成的路由表。
  • Binding Key(绑定键):Exchange与Queue的绑定关系,用于匹配Routing Key。最大长度255 字节。
  • Broker(消息队列服务进程):RabbitMQ Server,服务器实体。

生产者:

(1) 生产者连接到RabbitMQ Broker,建立一个连接( Connection)开启一个信道(Channel)
(2) 生产者声明一个交换器,并设置相关属性,比如交换机类型、是否持久化等
(3) 生产者声明一个队列井设置相关属性,比如是否排他、是否持久化、是否自动删除等
(4) 生产者通过路由键将交换器和队列绑定起来
(5) 生产者发送消息至RabbitMQ Broker,其中包含路由键、交换器等信息。
(6) 相应的交换器根据接收到的路由键查找相匹配的队列。
(7) 如果找到,则将从生产者发送过来的消息存入相应的队列中。
(8) 如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者
(9) 关闭信道。
(10) 关闭连接。

消费者:

(1) 消费者连接到RabbitMQ Broker ,建立一个连接(Connection),开启一个信道(Channel) 。
(2) 消费者向RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数,
(3) 等待RabbitMQ Broker 回应并投递相应队列中的消息,消费者接收消息。
(4) 消费者确认(ack) 接收到的消息。
(5) RabbitMQ 从队列中删除相应己经被确认的消息。
(6) 关闭信道。
(7)关闭连接。

二、消息模型

1、基本消息模型

在上图的模型中,有以下概念:

  • P:生产者,也就是要发送消息的程序

  • C:消费者:消息的接受者,会一直等待消息到来。

  • queue:消息队列,图中红色部分。可以缓存消息;生产者向其中投递消息,消费者从其中取出消息。

不用显示声明交换机,只需声明一个队列

生产者指定队列名发送消息给MQ,然后会有一个默认的交换机将消息转发给这个队列。

消费者负责监听这个队列,一有消息就会得到通知做出响应。

2、工作队列模式(Work queues)


和简单队列模式基本一样,不过有一点不同,该模式有多个消费者在监听队列。

RabbitMQ会以轮询的方式将消息发给多个消费者确保一条消息只会被一个消费者消费

3、发布订阅模式(Publish/subscribe)


和上面2种模式默认提供交换机不同的是,该模式需要显示声明交换机,

然后可以创建多个队列和这个交换机进行绑定。

生产者发消息给mq时需要指定交换机,然后交换机将消息转发给与自己绑定的所有队列

消费者监听指定的队列获得消息。每个队列可以有多个消费者监听,同样也是以轮询的机制发给消费者。

4、Routing 模式

和发布订阅模式不同的是,队列绑定交换机时需要指定一个routingkey

那么生产者发送消息时不仅需要指定交换机还需要指定routingkey

这样的话交换机就会把消息转发给跟自己绑定并且routingkey相匹配的队列

5、Topic模式

和Routing模式唯一的不同就是可以设置带有通配符进行模糊匹配的routingkey

6、heard模式

和Routing模式的不同就是取消了routing 使用键值对的方式作为routing

RabbitMQ原理解析相关推荐

  1. 分布式架构原理解析常见问题解决

    大家觉得写还可以,可以点赞.收藏.关注一下吧! 也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn 分布式架构原理解析常见问题解决 1. 分 ...

  2. Spark Shuffle原理解析

    Spark Shuffle原理解析 一:到底什么是Shuffle? Shuffle中文翻译为"洗牌",需要Shuffle的关键性原因是某种具有共同特征的数据需要最终汇聚到一个计算节 ...

  3. 秋色园QBlog技术原理解析:性能优化篇:用户和文章计数器方案(十七)

    2019独角兽企业重金招聘Python工程师标准>>> 上节概要: 上节 秋色园QBlog技术原理解析:性能优化篇:access的并发极限及分库分散并发方案(十六)  中, 介绍了 ...

  4. Tomcat 架构原理解析到架构设计借鉴

    ‍ 点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 Tomcat 架构原理解析到架构设计借鉴 Tomcat 发展这 ...

  5. 秋色园QBlog技术原理解析:性能优化篇:数据库文章表分表及分库减压方案(十五)...

    文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色 ...

  6. CSS实现元素居中原理解析

    原文:CSS实现元素居中原理解析 在 CSS 中要设置元素水平垂直居中是一个非常常见的需求了.但就是这样一个从理论上来看似乎实现起来极其简单的,在实践中,它往往难住了很多人. 让元素水平居中相对比较简 ...

  7. 秋色园QBlog技术原理解析:Web之页面处理-内容填充(八)

    文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色 ...

  8. 秋色园QBlog技术原理解析:UrlRewrite之无后缀URL原理(三)

    文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 本节,将从 ...

  9. Android之Butterknife原理解析

    转载请标明出处:[顾林海的博客] 个人开发的微信小程序,目前功能是书籍推荐,后续会完善一些新功能,希望大家多多支持! ##前言 Butterknife是一个专注于Android系统的View注入框架, ...

最新文章

  1. 是什么专业_自考什么专业容易就业
  2. BG.Hive - part1
  3. JAVA基础知识之字节和字符
  4. 2014-7-29-阿里电面-第一轮
  5. 一、人工智能数学基础——线性代数
  6. java中哪些可以私有化_《Java基础学习笔记》JAVA修饰符之私有化(Private)
  7. mysql3.5.2 下载_mybatis 3.5.2 jar 下载
  8. 安卓手机可以改鸿蒙吗,华为鸿蒙2.0可以替代安卓吗,华为鸿蒙2.0优势在哪
  9. 快速学习R语言的经验分享
  10. SAP MM模块-实施顾问岗位-面试手册-面试准备
  11. Rust 生命周期太难学、最想实现与 C++ 互操作,Rust 2020 调查报告发布!
  12. 加密货币挖矿太火造成显卡短缺,AMD、英伟达能躺着赚钱嘛?
  13. html的3d旋转木马插件,纯js超酷3D旋转木马特效插件
  14. 阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第4节 方法引用_5_方法引用_通过this引用本类的成员...
  15. php给超链接添加图标,图片超链接怎么设置
  16. 如何恢复SVN被删除文件、文件夹
  17. 大数据经典实验案例-WordCount原理详解和代码书写
  18. Exchange2010---反垃圾邮件配置
  19. ggsurvplot_combine R语言 一张图内画多条生存曲线
  20. 设置Excel表格“只读模式”的两种方法

热门文章

  1. 在 SAP 故乡,感受「边缘智能」之变
  2. java学习day38(Linux)Linux、命令
  3. Flowable定时器与实时流程图
  4. 【小白手册】超实用Python入门指南!
  5. 全国计算机化学年会,俞汝勤院士获中国化学会首届计算机化学终身成就奖
  6. 化学计量学(2)—线性回归、逐步回归原理与实现流程
  7. 泛微oa流程表单之开始时间与结束时间限制在本周且不能跨月
  8. winscp连接nas root账户拒绝访问_树莓派 3B 结合 NextCloud PI 搭建皮米级 NAS 家庭储存...
  9. PMBOK史上最大的改版,你知道到底有什么精华嘛?
  10. 碳基生命与硅基生命之间的一场思维碰撞