关于java:消息队列MQ剖析场景性能选型

33次阅读

共计 3134 个字符,预计需要花费 8 分钟才能阅读完成。

这篇文章次要围绕以下几个面试问题进行探讨。

  1. 为什么应用音讯队列?
  2. 音讯队列有什么长处和毛病?
  3. Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么长处和毛病?

面试官心理剖析

其实面试官次要是想看看:

第一,你知不知道你们零碎里为什么要用音讯队列这个货色?
不少候选人,说本人我的项目里用了 Redis、MQ,然而其实他并不知道本人为什么要用这个货色。其实说白了,就是为了用而用,或者是他人设计的架构,他从头到尾都没思考过。
没有对本人的架构问过为什么的人,肯定是平时没有思考的人,面试官对这类候选人印象通常很不好。因为面试官放心你进了团队之后只会木头木脑的干呆活儿,不会本人思考。

第二,你既然用了音讯队列这个货色,你知不知道用了有什么益处 & 害处?
你要是没思考过这个,那你自觉弄个 MQ 进零碎里,前面出了问题你是不是就本人溜了给公司留坑?你要是没思考过引入一个技术可能存在的弊病和危险,面试官把这类候选人招进来了,根本可能就是挖坑型选手。就怕你干 1 年挖一堆坑,本人跳槽了,给公司留下无穷后患。

第三,既然你用了 MQ,可能是某一种 MQ,那么你过后做没做过调研?
你别傻乎乎的本人拍脑袋看集体爱好就瞎用了一个 MQ,比方 Kafka,甚至都从没调研过业界风行的 MQ 到底有哪几种。每一个 MQ 的长处和毛病是什么。每一个 MQ 没有相对的好坏,然而就是看用在哪个场景能够取长补短,利用其劣势,躲避其劣势。
如果是一个不思考技术选型的候选人招进了团队,leader 交给他一个工作,去设计个什么零碎,他在外面用一些技术,可能都没思考过选型,最初选的技术可能并不一定适合,一样是留坑。

先说一下音讯队列常见的应用场景吧,其实场景有很多,然而比拟外围的有 3 个:解耦、异步、削峰。

解耦

看这么个场景。A 零碎发送数据到 BCD 三个零碎,通过接口调用发送。如果 E 零碎也要这个数据呢?那如果 C 零碎当初不须要了呢?A 零碎负责人简直解体 ……

在这个场景中,A 零碎跟其它各种乌七八糟的零碎重大耦合,A 零碎产生一条比拟要害的数据,很多零碎都须要 A 零碎将这个数据发送过去。A 零碎要时时刻刻思考 BCDE 四个零碎如果挂了该咋办?要不要重发,要不要把音讯存起来?头发都白了啊!

如果应用 MQ,A 零碎产生一条数据,发送到 MQ 外面去,哪个零碎须要数据本人去 MQ 外面生产。如果新零碎须要数据,间接从 MQ 里生产即可;如果某个零碎不须要这条数据了,就勾销对 MQ 音讯的生产即可。这样下来,A 零碎压根儿不须要去思考要给谁发送数据,不须要保护这个代码,也不须要思考人家是否调用胜利、失败超时等状况。

总结:通过一个 MQ,Pub/Sub 公布订阅音讯这么一个模型,A 零碎就跟其它零碎彻底解耦了。

面试技巧:你须要去考虑一下你负责的零碎中是否有相似的场景,就是一个零碎或者一个模块,调用了多个零碎或者模块,相互之间的调用很简单,保护起来很麻烦。然而其实这个调用是不须要间接同步调用接口的,如果用 MQ 给它异步化解耦,也是能够的,你就须要去思考在你的我的项目里,是不是能够使用这个 MQ 去进行零碎的解耦。在简历中体现进去这块货色,用 MQ 作解耦。

异步

再来看一个场景,A 零碎接管一个申请,须要在本人本地写库,还须要在 BCD 三个零碎写库,本人本地写库要 3ms,BCD 三个零碎别离写库要 300ms、450ms、200ms。最终申请总延时是 3 + 300 + 450 + 200 = 953ms,靠近 1s,用户感觉搞个什么货色,慢死了慢死了。用户通过浏览器发动申请,期待个 1s,这简直是不可承受的。

个别互联网类的企业,对于用户间接的操作,个别要求是每个申请都必须在 200 ms 以内实现,对用户简直是无感知的。

如果应用 MQ,那么 A 零碎间断发送 3 条音讯到 MQ 队列中,如果耗时 5ms,A 零碎从承受一个申请到返回响应给用户,总时长是 3 + 5 = 8ms,对于用户而言,其实感觉上就是点个按钮,8ms 当前就间接返回了,爽!网站做得真好,真快!

削峰

每天 0:00 到 12:00,A 零碎惊涛骇浪,每秒并发申请数量就 50 个。后果每次一到 12:00 ~ 13:00,每秒并发申请数量忽然会暴增到 5k+ 条。然而零碎是间接基于 MySQL 的,大量的申请涌入 MySQL,每秒钟对 MySQL 执行约 5k 条 SQL。

个别的 MySQL,扛到每秒 2k 个申请就差不多了,如果每秒申请到 5k 的话,可能就间接把 MySQL 给打死了,导致系统解体,用户也就没法再应用零碎了。

然而高峰期一过,到了下午的时候,就成了低峰期,可能也就 1w 的用户同时在网站上操作,每秒中的申请数量可能也就 50 个申请,对整个零碎简直没有任何的压力。

如果应用 MQ,每秒 5k 个申请写入 MQ,A 零碎每秒钟最多解决 2k 个申请,因为 MySQL 每秒钟最多解决 2k 个。A 零碎从 MQ 中缓缓拉取申请,每秒钟就拉取 2k 个申请,不要超过本人每秒能解决的最大申请数量就 ok,这样下来,哪怕是高峰期的时候,A 零碎也相对不会挂掉。而 MQ 每秒钟 5k 个申请进来,就 2k 个申请进来,后果就导致在中午高峰期(1 个小时),可能有几十万甚至几百万的申请积压在 MQ 中。

这个短暂的高峰期积压是 ok 的,因为高峰期过了之后,每秒钟就 50 个申请进 MQ,然而 A 零碎仍然会依照每秒 2k 个申请的速度在解决。所以说,只有高峰期一过,A 零碎就会疾速将积压的音讯给解决掉。

音讯队列有什么优缺点

长处下面曾经说了,就是在非凡场景下有其对应的益处,解耦、异步、削峰。

毛病有以下几个:

  - 零碎可用性升高
 零碎引入的内部依赖越多,越容易挂掉。原本你就是 A 零碎调用 BCD 三个零碎的接口就好了,人 ABCD 四个零碎好好的,没啥问题,你偏加个 MQ 进来,万一 MQ 挂了咋整,MQ 一挂,整套零碎解体的,你不就完了?如何保障音讯队列的高可用。- 零碎复杂度进步
 硬生生加个 MQ 进来,你怎么保障音讯没有反复生产?怎么解决音讯失落的状况?怎么保障消息传递的程序性?头大头大,问题一大堆,苦楚不已。- 一致性问题
 A 零碎解决完了间接返回胜利了,人都认为你这个申请就胜利了;然而问题是,要是 BCD 三个零碎那里,BD 两个零碎写库胜利了,后果 C 零碎写库失败了,咋整?你这数据就不统一了。

所以音讯队列理论是一种非常复杂的架构,你引入它有很多益处,然而也得针对它带来的害处做各种额定的技术计划和架构来躲避掉,做好之后,你会发现,妈呀,零碎复杂度晋升了一个数量级,兴许是简单了 10 倍。然而关键时刻,用,还是得用的。

Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?

综上,各种比照之后,有如下倡议:

个别的业务零碎要引入 MQ,最早大家都用 ActiveMQ,然而当初的确大家用的不多了,没通过大规模吞吐量场景的验证,社区也不是很沉闷,所以大家还是算了吧,我集体不举荐用这个了;

起初大家开始用 RabbitMQ,然而的确 erlang 语言阻止了大量的 Java 工程师去深入研究和掌控它,对公司而言,简直处于不可控的状态,然而的确人家是开源的,比较稳定的反对,活跃度也高;

不过当初的确越来越多的公司会去用 RocketMQ,的确很不错,毕竟是阿里出品,但社区可能有忽然黄掉的危险(目前 RocketMQ 已捐给 Apache,但 GitHub 上的活跃度其实不算高)对本人公司技术实力有相对自信的,举荐用 RocketMQ,否则回去老老实实用 RabbitMQ 吧,人家有沉闷的开源社区,相对不会黄。

所以中小型公司,技术实力较为个别,技术挑战不是特地高,用 RabbitMQ 是不错的抉择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的抉择。

如果是大数据畛域的实时计算、日志采集等场景,用 Kafka 是业内规范的,相对没问题,社区活跃度很高,相对不会黄,何况简直是全世界这个畛域的事实性标准。

正文完
 0