为什么需要学习RocketMQ?
前几天有幸看到了一篇3Y的文章,里面提及到刚进入职场后怎么样计划和过度这段不尴不尬的职场初期。
对于很多人,乃至我个人而言,自从校招签约了自己比较心仪的工作之后就在忙这忙那,不是毕业设计,就是各种毕业档案事宜,可以说是忙得昏天暗地。逐渐的自己也远离了代码,远离了学习。也许是真的繁琐的事儿太多,也可能是我厌倦了春秋招那段时间的状态,半夜刷题,一天三场笔试(2小时起)三场面试(最少也是半小时起),加各种复盘,可以说是需要每时每刻都要保持着紧张刺激的心态,去和面试官,和算法题,和各种知识点逻辑题大战几百回合,有时候还要承受被战败(pass)的滋味,相信经历过春秋招几十几百回合笔面试的伙伴都会了解那段时间。
所以,我觉得在我签约后我真的松懈了很多,盲目了很多,尽管也会疑问工作后该学习什么,怎么学习,从哪里下手等等问题,一心想着学习各种市面上流行牛逼的技术框架,但又担心无法在工作中得到实战锻炼,一正一反的心理导致了各种推延学习的心理,一直耗着,最终就是虚度光阴,久久不能明确自己的学习和过度计划,直到看到3Y的文章,我才明白,坚持学习,度过职场初期从身边出发,从现下工作中能用到的技术开始。
我在公司写的第一个接口就是利用模拟RocketMQ消息来测试代码的,同时我对消息队列也是非常感兴趣的,以前也有一些了解,但那么多消息队列我是不知道要仔细的去学啥,本来的安排是想去学习Kafka,但是就像3Y所说的工作后学习的技术最好是工作中能用到的,这也帮助我明确了我要认真的学习RocketMQ。
学习嘛!得需要带着问题去学习才是高效的!
一.为什么要引入MQ?有什么好处,也带来什么问题?如何解决?
这个是面试的时候经常被问及的问题,也许有很多人会觉得这些问题明显是背八股文,但是如果站在公司的角度去思考还是有一定的道理的!
如果你不知道为什么引入MQ,只是为了用而去用,公司也会担心你进来之后只会埋头苦干,不会自己去思考;
如果你不明白引入MQ有哪些好处和不足,公司也会担心你进来干个一两年中疯狂引入新技术,可能当下问题是解决了,但潜在的问题却不会去分析和评估以及解决,等到你离开了公司后,给公司留下一堆问题,就相当于公司花钱找了个挖坑的伙计;
。。。。。。
也是因此,我们在工作中用到的技术不仅要会用,而且还要知道相关利弊!
百度的解释:
MQ的作用
消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构
解耦:一个业务需要多个模块共同实现,或者一条消息有多个系统需要对应处理,只需要主业务完成以后,发送一条MQ,其余模块消费MQ消息,即可实现业务,降低模块之间的耦合
异步:主业务执行结束后从属业务通过MQ,异步执行,减低业务的响应时间,提高用户体验
削峰:高并发情况下,业务异步处理,提供高峰期业务处理能力,避免系统瘫痪
MQ的缺点
1、系统可用性降低。依赖服务也多,服务越容易挂掉。需要考虑MQ瘫痪的情况
2、系统复杂性提高。需要考虑消息丢失、消息重复消费、消息传递的顺序性
3、业务一致性。主业务和从属业务一致性的处理
其实第一次仅仅看到这些文字描述时我是懵的!所以可以利用画图来更好的理解:
解耦:
(1)引入MQ前:
(2)引入MQ后:
看完引入MQ前后之间的对比图后,我算是真的理解了什么叫解耦!
通过MQ的发布和订阅模型,系统A就跟其他系统彻底解耦
在项目中如果存在有类似的场景,1个系统或者一个模块,调用了多个系统或者模块,相互之间的调用很复杂,维护起来很麻烦时,你可以考虑引入MQ,去帮助实现系统解耦
异步:
(1)引入MQ前:
(2)引入MQ后:
异步处理最直观的体验就是用户点击一个按钮所需等待时间大大降低
一般一个接口的响应时长低于200ms时,用户无法肉眼感知细微差距,在这样的背景下,我们尽量会使用MQ去保障一些调用链较长的接口的响应时间缩小到200ms以内,为用户提供更快捷更好的直观体验
削峰:
(1)引入MQ前:
(2)引入MQ后:
削峰尽管会带来一些消息挤压,响应用户时间变长等的不好影响,但总比将数据库打死导致系统瘫痪不可用强上很多
了解引入MQ的三大作用之后,可谓是明白了MQ的好处多多,但是引入MQ之后又会给系统带来什么样的新问题呢?
1.系统可用性降低
一旦MQ挂了,那么整个系统就崩了,所以在引入MQ的同时需要考虑到怎么样让MQ实现高可用(集群)
2.如何保证数据一致性
如果A系统需要调用B、C、D三个系统来完成用户的一次操作,过程中B、C成功返回所需数据,但D却调用失败了,如果D恰好是写操作,此时就会产生B、C、D数据不一致的情况,此时需要考虑到更多的设计去保证数据的一致性(事务、最终一致)
3.如何解决消息堆积、重复消息、消息丢失、顺序消费等问题
在削峰或消息消费能力低于生产能力的场景下,MQ中会堆积大量的在消息从而影响业务功能和降低用户体验等问题
当消费者确认超时或失败,以及Kafka和RocketMQ回调的时候都会造成重复消息问题
发送期间,可能因为网络、持久化时磁盘异常、Kafka和RocketMQ回调、服务器重启等等各式各样的问题而导致消息丢失
在一些场景中需要保证消息的顺序消费,但如果出现路由不一致、多线程消费、消息异常等情况都会造成消费顺序紊乱
4.系统复杂度提升
因为引入了MQ,那么关注点就在原来的基础上增加,MQ与下游之间、MQ与上游之间的一系列问题,从而导致系统复杂度上升
关于引入MQ后的一系列问,个人没有经验,推荐一个个人觉得比较好的大佬文章如何解决MQ遇到的问题
了解了引入MQ的利弊之后,那么就需要考虑引入哪一种MQ才能对自身业务系统较为适用,目前市面上流行的MQ各有千秋,没有绝对的好与坏,只存在适不适应自身业务场景需求
开始进行MQ选型!
二.公司为啥用RocketMQ?为什么不用其他的消息队列中间件?
关于这个问题我曾经看到一个很现实,也很符合大多数普通的cv工程师的回答:
用什么技术是架构师决定的,我只负责CRUD,我哪知道为什么选这个,你问我我去问谁?
但现实中要是这样回答,我估计基本凉凉了,当然我们学习也不一定是为了面试(虽然是这样)。
当我准备开始学习RocketMQ之时,也有这样的疑问,同样的我也不知道为啥公司要用它,但我的第一念头就是想了解RocketMQ和其他消息中间件之间的区别,它有什么优势,适用于哪些场景,于是我就去找了一张性能对比图:
较全对比图(ActiveMQ省):
ActiveMQ:
优势:
ActiveMQ采用消息推送的方式实现,最适合的场景是默认消息都可在短时间内被消费,高可用性相对其他MQ而言只能说一般,MQ领域的功能比较完善
劣势:
单机吞吐量低,由于ActiveMQ需要建立索引,导致吞吐量下降,随着数据量越大,查找和消费消息就越慢,消息积压程度与消息速度成反比
无分片,MS并没有提供消息中间件的集群、分片机制等功能的实现,如果一台服务器不能承受更多消息,则需要横向拆分,官方并没有提供这个功能,需要自己实现
场景:
小项目对TPS较低的系统,使用起来比较简单,而且可控,还提供可视化界面进行监控和管理;因为其不支持自动分片机制,对于消息量巨大的项目则不适用
RabbitMQ:
优势:
RabbitMQ支持集群化、高可用部署架构、消息高可靠支持,监控管理界面也非常好用,最重要的是它的时效性相对其他MQ来说是最好的,能保持在微秒以内,同时人家社区开源,且非常活跃,不用担心出现bug,没圈子讨论
劣势:
RabbitMQ是由Erlang语言开发的,在国内非游戏行业来说鲜有大牛能够对它进行二次开发,也导致了公司对其掌控度降低,好感度也会随之降低
RocketMQ:
优势:
RocketMQ同样也是支持集群化、高可用部署架构、消息高可靠支持等,另外其单机吞吐量能达到十万级别,为高吞吐量,同时其为分布式架构,在系统的扩展性上十分良好,已经抗住了阿里各种节日高并发的实战检验,应该是没有问题的。还有就是它是由Java语言开发的,国内的爪哇大牛还是挺多的,如果对其不满意或是不满足公司的业务需求,可以进行二次开发
劣势:
听说官方文档比较简单,所以推荐去看看Apache的文档Apache RocketMQ用户指南
Kafka:
优势:
这是一个大数据处理的YYDS,极高的吞吐量,可达到百万级,有较高的可用性以及可靠性,也是分布式的,可以任意扩展。
劣势:
功能相较简单,不支持MQTT协议,也不支持事务,会造成消息丢失和重复消费,另外就是它的监控不太完善,需要安装插件
至于选择哪一种MQ,可以根据它们各自的优缺点和自身项目情况去评估及确定。
而我工作的公司选择了RocketMQ,我的个人计划是通过PDF文档先了解部分能理解的理论知识后,再去看RocketMQ的代码,或者是边看边百度以及咨询大佬,不然只看文档很枯燥,只看代码也会满脸懵
于是找了一本《RocketMQ技术内幕》,同时也clone了代码,这里记录了一下怎么让代码跑起来
1.地址:
github: https://github.com/apache/rocketmq
gitee: https://gitee.com/apache/rocketmq
2.加载完成依赖
3.启动Namesrv
(1)在Namesrv根目录下创建conf文件夹,然后复制distribution\conf项目下的broker.conf和logback_broker.xml两个文件到Namesrv新创建的conf下
(2)修改brok r.conf如下:
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
###########################################
#配置存储位置
storePathRootDir=D:\\rocketmq\\namesrv\\store
#commitlog 存储路径
storePathCommitLog=D:\\rocketmq\\namesrv\\store\\commitlog
#消费队列存储路径
storePathConsumeQueue=D:\\rocketmq\\namesrv\\store\\consumequeue
#消息索引存储路径
storePathIndex=D:\\rocketmq\\namesrv\\store\\index
#checkpoint文件存储路径
storeCheckPoint=D:\\rocketmq\\namesrv\\store\\checkpoint
#abort文件存储路径
abortFile=D:\\rocketmq\\namesrv\\store\\abort
(3)再复制一份logback_broker.xml,并修改为logback_namesrv.xml,最后,将这两个文件中的${user.home}替换成自己的日志存储文件路径
(4)配置启动参数
(5)启动
4.启动broker
(1)配置启动参数:
第一个参数为namesrv下conf文件夹中的broker.conf文件
第二个参数为自动获取
第三个参数为namesrv项目的绝对路径
(2)启动
(3)如果ip和本机的不一致,则需要修改distribution项目下conf文件夹下的 broker.conf 文件,在其中增加一个 增加brokerIP1 = 127.0.0.1,再重启即可
RocketMQ学习笔记(一)就先到这里,后期再继续更新,坚持破脑子敌不过烂笔头!