Java学习:Java从入门到精通总结
Spring系列推荐:Spring源码解析
绝对不一样的职场干货:大厂最佳实践经验指南
最近更新:2022年4月28日
个人简介:通信工程本硕、Java程序员。做过科研,发过专利,行业瓶颈期更需要大家一起来报团取暖!
点赞 收藏 ⭐留言 都是我最大的动力!
各位读者大家好,经过一段时间的筹备,我的新专栏《深入浅出RocketMQ设计思想》今天正式开始更文啦。
为什么要开这个专栏呢?
我的观点是,优秀的程序员的技术栈中不能只有CRUD,虽然我们在工作中只会使用消息队列来实现业务,并没有机会参与到它的开发流程中,然而,消息队列几乎是每个后端程序员都会用到的中间件,且它的功能很简单,大家肯定可以看一下文档,几分钟就写出一个Demo。但是把消息队列真正应用到生产系统中,就没那么简单了:
最后,希望通过这个专栏,能够让你对消息队列的掌握情况、架构能力都有一个质的飞跃!
说到消息中间件,小伙伴们一定不会陌生,它的使用场景包括但不限于:
服务解耦
削峰填谷
异步化缓冲
是业务中不可或缺的一大中间件利器,接下来我会用一个专栏的篇幅带大家揭开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的场景有很多,比如就拿电商场景为例吧,大家都知道,在每年双十一的时候,淘宝的后台服务器都会承载巨大的压力,如果将那一瞬间的流量全部打到业务服务器上,可能瞬间服务就宕机了,但如果我们先把用户们发来的消息堆积起来,具体的业务服务器根据自己的实际情况从消息队列里拿消息再执行对应的操作,就可以避免瞬时压力过大带来的问题,这就是削峰填谷。
当你在淘宝里点了下单按钮之后,其实后台是做了非常多的工作的:
如下图所示,A,B,C,D是让用户发起付款的几个流程,E是通知卖家发货的流程,我们完全可以将E过程解耦,让B,C,D同时进行,来加快整条链路的执行过程:
目前主流的MQ主要有四种:
从上到下技术由旧到新。具体如何做技术选型大家可以参考下表:
ActiveMQ | RabbitMQ | Kafka | RocketMQ | |
---|---|---|---|---|
开发语言 | Java | Erlang | Scala | Java |
单体吞吐量 | 万级 | 万级 | 10万级 | 10万级 |
时延 | ms级 | us级 | ms级 | ms级 |
可用性 | 中 | 中 | 高 | 高 |
特点 | 最经典的产品,很多公司沿用至今,发展时间较长所以有很多文档 | 并发能力强,延时很低 | 只支持主要的MQ功能,在大数据领域应用较广泛 | 继承了Kafka的优秀设计,功能更完备,扩展性好 |
此外,也可以从以下几点来思考公司到底适合哪一种消息队列:
上面我们介绍了消息中间件那么多的好处,但并不代表我们所有的项目都要“无脑”引入消息队列,毕竟过犹不及是真理。
一旦我们决定要引入MQ,首先要思考的问题就是它是否会为整个项目带来风险?可以从以下几点角度进行思考:
系统复杂度:项目引入MQ势必会增加系统的复杂度,比如要考虑如何实现最终一致?如何保证消息不被重复消费?如何保证消息可靠传输?等等等等,我们是否可以接收这样的复杂度提高。
维护成本:系统复杂度增加之后,就会需要额外的成本来进行架构和技术方案的设计,我们是否接受增加额外的人力成本。
但实际上,当下国内互联网公司往往都是糙快猛的发展模式,产品快速迭代已经成为企业的一个基本要求,所以项目往往采用微服务的架构,这样一来,引入MQ也就成为必然。
这一部分的目的也是要告诉大家,选用MQ时要做好详细的设计
上面介绍了那么多,可能大家对于如何使用MQ还是一头雾水,这一节就给大家列举一下使用MQ的几个经典案例。
假设现在有一个用户登录的需求,由于我们应用的安全级别设置的比较高,所以产品要求所有注册用户必须 手机 + 邮箱 双重验证后才算注册成功。
用户发起登录请求,后台接收到请求之后先发送验证邮件,之后发送验证短信,最后反馈给用户响应,假设一共需要150ms。
如果引入MQ和异步处理的话:
如果使用了消息队列 + 异步处理,就会使得响应时长变为50ms,分析如下:
所以综合来看,1s时间内能够处理的登录请求从同步时的7次到异步时的20次,性能大约提升了3倍!
还是回到上一部分电商的例子,用户下单后,订单系统需要通知库存系统进行扣减库存的操作,直觉思路是直接在订单系统里调用库存系统,等库存扣减完毕后再执行后续的操作:
这样的调用方式有一个明显的缺点,那就是一旦库存系统挂了,就会导致订单系统也一直返回失败,用户无法正常下单,两个系统强耦合在一起,对此,我们可以采取如下的方式:
订单系统在用户下单后写入一条消息后就直接返回;库存系统读取这条消息消费,减去对应商品的库存。
这样一来,即便库存系统挂了也不影响用户下单,因为订单系统在写入消息后就结束了,实现了二者的解耦。
日志收集系统负责采集日志数据,写入MQ;日志处理系统负责处理MQ中的日志数据。
消息队列一般都基于高效通信框架,例如Netty
,因此可以用来实现进程间通信: