写点什么

RabbitMQ 的深入理解和最简单的用途说明

作者:小小怪下士
  • 2022 年 9 月 22 日
    湖南
  • 本文字数:2029 字

    阅读完需:约 7 分钟

RabbitMQ 在上一家公司已经接触过了, 但是懵懵懂懂的. 不是很清楚. 具体怎么个逻辑. 

这次公司打算搭建新的系统. 领导要求研究一下 MQ. 

经过研究得出的结论是. MSMQ 的设计理念不适合做系统的底层框架. 他不适合做分布式系统. 最主要的是. MSMQ 如果没有消费者, 默认消息是一直存在的. 

而 RabbitMQ 的设计理念是.只要有接收消息的队列. 邮件就会存放到队列里. 直到订阅人取走. . 如果没有可以接收这个消息的消息队列. 默认是抛弃这个消息的..

下面就把我的研究结果写一下.

如何在新的系统中使用 RabbitMQ.

系统设计的两个重大问题. 

第一条要满足未来的业务需求的不断变化和增加. 也就是可扩展性. 

第二条要满足性能的可伸缩性. 也就是可集群性…通过增加机器能处理更多的请求 

第三条要解耦合. 

如果不解耦合, 未来业务增加或变更的时候你还在修改 3 年前写的代码.试问你有多大的把握保证升级好系统不出问题? 如何可以写新的代码而不用修改老代码所带来的好处谁都知道… 

第四条简单易懂.

以上 4 条在任何一个系统中都要遵循的原则. 以前是无法做到的. 自从有了 MQ 以后. 这些都可以同时做到了. 

以前的设计理念是把系统看作一个人,按照工作的指令从上到下的执行. 

现在要建立的概念是, 把系统的各个功能看作不同的人. 人与人之间的沟通通过消息进行交流传递信息… 

有了 MQ 以后把一个人的事情分给了不同的人, 分工合作所带来的好处是专业化, 并行化. 当然也引入了一些麻烦,性能开销多一些, 工作任务的完整性不能立即得到反馈.幸好我们可以通过最终一致性.来解决这个麻烦的问题…

下面进入正题.

第一个问题 RabbitMQ 是如何支持可扩展性的.


如上图, 寄件人 P 是系统的一个功能模块. 用来发送消息. 一般是在某些重要的业务状态变更时发送消息. 例如: 新订单产生时, 订单已打包时, 订单已出库时, 订单已发出时.

那么当事件 新订单产生时, 我们需要把这个信息告诉谁呢? 给财务? 还是给仓库发货? 

这个地方最大的重点是. 当事件产生时. 根本不关心. 该投递给谁. 

我只要把我的重要的信息投到这个乱七八糟的 MQ 系统即可. 其它人你该干嘛干嘛. 反正我的任务完成了. (有没有甩手掌柜的感觉..)

我只要告诉系统,我的事件属于那一类. 

例如: “某某省.某某市.某某公司.产生新订单” 

那么这个地址就属于 投递地址.. 至于这个地址具体投到哪个邮箱那是邮局的事情. 

当然还有一些具体的订单内容也属于要告诉系统的内容.

那么下一个问题来了, 邮局怎么知道 你的这个消息应该投递给谁? 

参考我们现实世界中的邮寄系统.是默认的省市县这么投递的. 这是固定思维. 

但是我们的 MQ 系统中不是这样的. 是先有收件人的邮箱. (队列 Queue). MQ 才能投递. 否则就丢弃这个信息…

所以 MQ 系统应该先有收件人的邮箱 Queue 也就是队列. 才能接收到信息. 

再有邮局 

再有发信息的人.

RabbitMQ 能实现系统扩展的一个重要功能在于, 可以两个邮箱收同一个地址的信.

翻译成专业的话 RabbitMQ 可以 两个队列 Queue 订阅同一个 RoutingKey 的信息.. 

RabbitMQ 在投递的时候,会把一份信息,投递到多个队列邮箱中 Queue… 

这是系统可扩展性的基础.

第二个问题 RabbitMQ 如何满足性能的可伸缩性. 也就是可集群性

先上图 


从上图, 可以看到. 性能扩展的关键点就在于 订阅人 C1, 订阅人 C2 轮流收到邮箱队列里面的信息, 订阅人 C1 和订阅人 C2 收到的信息内容不同, 但都属于同一类…. 

所以. 订阅人 C1 和订阅人 C2 是干同一种工作的客户端.用来提高处理能力.

上面说完了,如何使用. 下面再分析一下几个关注点.

如果订阅人的 down 机了. 信息会丢失吗?

    事实上是不会的. 只要有邮箱(队列 Queue)存在.信息就一直存在, 除非订阅人去取走.

如果订阅人一直 down 机, 邮箱队列能存多少信息?会不会爆掉?

  理论上和实际上都是有上限的不可能无限多. 具体多少看硬盘吧..我没测到过上限.

我这篇文章并不打算讲解邮局的 4 种投递模式. 有其它文章讲的很好. 我只打算使用 topic 这种模式. 因为它更灵活一些.

再说一下我的另外两个观点. 

不要在业务程序中用代码定义创建 邮局 ExChange. 和邮箱 Queue 队列 这属于系统设计者要构架的事情. 要有专门独立的程序和规则去创建. 这样可以统一管理事件类型.避免过多的乱七八糟的 RoutingKey 混乱.

我的理解认为 

消息系统的分布式可扩展的实现在于消息广播, 集群性的实现在于邮箱队列. 

RabbitMQ 是先广播后队列的.

Exchange: 就是邮局的概念等同于 中国邮政和顺丰快递、 

routingkey: 就是邮件地址的概念. 

queue: 就是邮箱接收软件,但是可以接收多个地址的邮件,通过 bind 实现。 

producer: 消息生产者,就是投递消息的程序。 

consumer:消息消费者,就是接受消息的程序。 

channel:消息通道,在客户端的每个连接里,可建立多个 channel,每个 channel 代表一个会话任务。

给大家推荐一个 Java 资料免费分享 vx:xiaoyanya_1 有分享的视频,还有思维导图群公告有视频,都是干货的,你可以下载来看。主要分享分布式架构、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm 大型分布式项目实战学习架构师视频。



用户头像

还未添加个人签名 2022.09.04 加入

热衷于分享java技术,一起交流学习,探讨技术。 需要Java相关资料的可以+v:xiaoyanya_1

评论

发布
暂无评论
RabbitMQ的深入理解和最简单的用途说明_Java_小小怪下士_InfoQ写作社区