初探篇初识消息队列 & RocketMQ

Posted 小王曾是少年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初探篇初识消息队列 & RocketMQ相关的知识,希望对你有一定的参考价值。

🍊 Java学习:Java从入门到精通总结

🍊 Spring系列推荐:Spring源码解析

🍊 绝对不一样的职场干货:大厂最佳实践经验指南


📆 最近更新:2022年4月28日

🍊 个人简介:通信工程本硕💪、Java程序员🌕。做过科研,发过专利,行业瓶颈期更需要大家一起来报团取暖!

🍊 点赞 👍 收藏 ⭐留言 📝 都是我最大的动力!


写在前面

各位读者大家好,经过一段时间的筹备,我的新专栏《深入浅出RocketMQ设计思想》今天正式开始更文啦。

为什么要开这个专栏呢?

我的观点是,优秀的程序员的技术栈中不能只有CRUD,虽然我们在工作中只会使用消息队列来实现业务,并没有机会参与到它的开发流程中,然而,消息队列几乎是每个后端程序员都会用到的中间件,且它的功能很简单,大家肯定可以看一下文档,几分钟就写出一个Demo。但是把消息队列真正应用到生产系统中,就没那么简单了:

  • 如果你只是有一些消息队列使用经验,对于常见的问题,可以根据经验来判断问题所在,对于一些没见过的问题,那就无能为力了
  • 如果你掌握了消息队列的实现原理,无论你遇到任何问题,都可以从原理层面来分析它的原因,再简单看一下它的 API 和相关配置项,就能很快知道该如何写出高性能并且可靠的程序。

最后,希望通过这个专栏,能够让你对消息队列的掌握情况、架构能力都有一个质的飞跃!


文章目录

【起源】RocketMQ的前世今生

说到消息中间件,小伙伴们一定不会陌生,它的使用场景包括但不限于:

  • 服务解耦

  • 削峰填谷

  • 异步化缓冲

是业务中不可或缺的一大中间件利器,接下来我会用一个专栏的篇幅带大家揭开RocketMQ的神秘面纱,它可是承载了每年淘宝双十一万亿流量的一大利器,是我们很可靠的小伙伴哦 ~


阿里巴巴消息中间件起源于2001年的五彩石项目,第一款消息中间件是Notify,支撑了后来前期双十一的消息流转任务,在淘宝和支付宝内得到广泛的使用。

到了2010年,B2B业务开始大规模使用ActiveMQ作为消息内核,但是随着阿里业务的快速发展,仍然急需一款支持顺序消息,拥有海量消息堆积能力的消息中间件,所以在这个大背景下Metamorphosis诞生,也就是MetaQ 1.x版本。

https://github.com/killme2008/Metamorphosis


Metaq 2.x 版本在后续迭代中也上线了,取代Notify在淘宝内部被广泛使用。


到2012年,MetaQ已经发展到了MetaQ 3.0,并且去除了一些集团内部的强依赖后,抽象出了通用的消息引擎RocketMQ。随后,集团将RocketMQ进行了开源,阿里的消息中间件正式走入了公众的视野。

所以集团内部员工口中的MetaQ其实就是RocketMQ,也是为数不多的集团内部和外部开源公用的一个中间件,其他类型的中间件如缓存、配置中心等等集团内部还是自己的工具其实还没有开源,相信随着时间的发展,公司还会向外输出更多的优秀中间件!


到2015年,RocketMQ已经经历了多年双十一的洗礼,在可用性、可靠性、稳定性、扩展性、安全性等方面都有出色的表现。与此同时,阿里大力发展云计算平台,阿里消息中间件基于RocketMQ推出了Aliware MQ 1.0,开始为阿里云上成千上万家企业提供消息服务。


到2016年,MetaQ在双十一承载了万亿级消息的流转,跨越了一个新的里程碑,同时RocketMQ进入 Apache 开源项目孵化,RocketMQ参考借鉴了优秀的开源消息中间件Apache Kafka,其消息的路由、存储、集群划分都借鉴了Kafka优秀的设计思路,并结合自身的"双十一”场景进行了合理的扩展和API丰富。

它的开源社区也是非常活跃,在世界上影响力非凡~

开源社区地址:https://github.com/alibaba/RocketMQ


接下来就请大家跟随着我的脚步,去探索RocketMQ的新世界吧 : )


通过上面的篇幅吗,我们宏观地介绍了RocketMQ的“前世今生”,明白了和它和MetaQ的关系,这一节开始就开始进入到正式知识环节啦。

既然要学RocketMQ,那么我们就需要先明白它是做什么的,以及为什么我们要用它,不要为了学习而学习,毕竟时间是很宝贵的。


何为消息中间件

消息队列,也就是常说的MQ(message queue)现在是企业内部系统消息流转的核心手段,它具有以下特点:

  • 低耦合
  • 消息可靠投递
  • 消息传播范围广
  • 可以控制流量(削峰填谷)
  • 数据最终一致性

上面提到的内容我会一一介绍,除此之外,本文还将带领大家从架构的角度理解消息中间件,了解消息在企业系统中的应用,以及MQ的工作原理与实际应用场景。


为什么要使用MQ

削峰填谷

使用MQ的场景有很多,比如就拿电商场景为例吧,大家都知道,在每年双十一的时候,淘宝的后台服务器都会承载巨大的压力,如果将那一瞬间的流量全部打到业务服务器上,可能瞬间服务就宕机了,但如果我们先把用户们发来的消息堆积起来,具体的业务服务器根据自己的实际情况从消息队列里拿消息再执行对应的操作,就可以避免瞬时压力过大带来的问题,这就是削峰填谷


服务解耦

当你在淘宝里点了下单按钮之后,其实后台是做了非常多的工作的:

  • 首先要核对你的基本信息,然后检查商品库存并扣减,然后计算优惠信息,然后拉取支付方式,支付成功后通知卖家发货等等等等,其中每一步的工作量也不小,如果我们将上面的过程全部写到一段代码里面的话,很可能前面某个环节一个小小的问题就会导致整个链路执行失败,用户体验就很差,这就是传统的强耦合的设计。
  • 对此,我们可以借助消息队列来进行解耦,当执行完一步后发送一条消息即可,下游链路读取到对应的消息后再执行进一步的操作,把同步操作变为异步操作,使得其中的一些任务同时执行。

如下图所示,A,B,C,D是让用户发起付款的几个流程,E是通知卖家发货的流程,我们完全可以将E过程解耦,让B,C,D同时进行,来加快整条链路的执行过程:



我应该怎么做技术选型?

目前主流的MQ主要有四种:

  • ActiveMQ
  • RabbitMQ
  • Kafka
  • RocketMQ

从上到下技术由旧到新。具体如何做技术选型大家可以参考下表:

ActiveMQRabbitMQKafkaRocketMQ
开发语言JavaErlangScalaJava
单体吞吐量万级万级10万级10万级
时延ms级us级ms级ms级
可用性
特点最经典的产品,很多公司沿用至今,发展时间较长所以有很多文档并发能力强,延时很低只支持主要的MQ功能,在大数据领域应用较广泛继承了Kafka的优秀设计,功能更完备,扩展性好
  • 如果是大数据应用场景,建议使用Kafka
  • 如果是中小型公司,建议使用RabbitMQ,因为软件的数据量并没有那么大,并且它的功能比Kafka完备,缺点是它是用Erlang语言开发的,阻碍了海量Java程序员对其完善
  • 大公司应该在Kafka和RocketMQ之前进行选择,因为大公司具有足够的数据量,也具有充足的资金搭建集群环境,甚至还能有专门的人力针对消息队列进行定制化开发

此外,也可以从以下几点来思考公司到底适合哪一种消息队列:

  1. 性能
  2. 功能完备程度
  3. 开发语言
  4. 是否有公司使用,效果如何?
  5. 社区的活跃程度以及文档详细度
  6. 员工学习成本
  7. 是否支持集群、分布式

谨慎使用消息中间件

上面我们介绍了消息中间件那么多的好处,但并不代表我们所有的项目都要“无脑”引入消息队列,毕竟过犹不及是真理。

一旦我们决定要引入MQ,首先要思考的问题就是它是否会为整个项目带来风险?可以从以下几点角度进行思考:

  1. 系统复杂度:项目引入MQ势必会增加系统的复杂度,比如要考虑如何实现最终一致?如何保证消息不被重复消费?如何保证消息可靠传输?等等等等,我们是否可以接收这样的复杂度提高。

  2. 维护成本:系统复杂度增加之后,就会需要额外的成本来进行架构和技术方案的设计,我们是否接受增加额外的人力成本。

但实际上,当下国内互联网公司往往都是糙快猛的发展模式,产品快速迭代已经成为企业的一个基本要求,所以项目往往采用微服务的架构,这样一来,引入MQ也就成为必然

这一部分的目的也是要告诉大家,选用MQ时要做好详细的设计


RocketMQ应用场景举例

上面介绍了那么多,可能大家对于如何使用MQ还是一头雾水,这一节就给大家列举一下使用MQ的几个经典案例。

异步处理

假设现在有一个用户登录的需求,由于我们应用的安全级别设置的比较高,所以产品要求所有注册用户必须 手机 + 邮箱 双重验证后才算注册成功。

如果采用串行的方式来设计这个流程的话:

用户发起登录请求,后台接收到请求之后先发送验证邮件,之后发送验证短信,最后反馈给用户响应,假设一共需要150ms。


如果引入MQ和异步处理的话:


如果使用了消息队列 + 异步处理,就会使得响应时长变为50ms,分析如下:

  1. 用户发起登录请求
  2. 登录模块在收到请求之后写入一条新消息到MQ里,这个过程基本不耗时间,此时就可以直接返回给用户响应了
  3. 后台系统从MQ中异步读取消息,执行各自的逻辑,用户收到短信后完成操作

所以综合来看,1s时间内能够处理的登录请求从同步时的7次到异步时的20次,性能大约提升了3倍!


应用解耦

还是回到上一部分电商的例子,用户下单后,订单系统需要通知库存系统进行扣减库存的操作,直觉思路是直接在订单系统里调用库存系统,等库存扣减完毕后再执行后续的操作:

这样的调用方式有一个明显的缺点,那就是一旦库存系统挂了,就会导致订单系统也一直返回失败,用户无法正常下单,两个系统强耦合在一起,对此,我们可以采取如下的方式:


订单系统在用户下单后写入一条消息后就直接返回;库存系统读取这条消息消费,减去对应商品的库存。

这样一来,即便库存系统挂了也不影响用户下单,因为订单系统在写入消息后就结束了,实现了二者的解耦。

日志处理


日志收集系统负责采集日志数据,写入MQ;日志处理系统负责处理MQ中的日志数据。

进程间通信

消息队列一般都基于高效通信框架,例如Netty,因此可以用来实现进程间通信:

分布式事务保证最终一致性

用户A向用户B转账,使用MQ来保证系统的最终一致性:

以上是关于初探篇初识消息队列 & RocketMQ的主要内容,如果未能解决你的问题,请参考以下文章

rocketmq初识

rocketmq初识

rocketmq初识

分布式消息队列RocketMQ&Kafka -- 消息的“顺序消费”

初识中间件之消息队列

RocketMQ:死信队列和消息幂等