面试官:为何使用消息队列?消息队列有什么优势和缺点?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景?

2022年05月15日 阅读数:4
这篇文章主要向大家介绍面试官:为何使用消息队列?消息队列有什么优势和缺点?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景?,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

【北京】 IT技术人员面对面试、跳槽、升职等问题,如何快速成长,得到大厂入门资格和升职加薪的筹码?与大厂技术大牛面对面交流,解答你的疑惑。《从职场小白到技术总监成长之路:个人职场焦虑与救赎》活动连接:码客 web

恭喜fpx,新王登基,lpl*b 咱们是冠军面试

面试题

  • 为何使用消息队列?
  • 消息队列有什么优势和缺点?
  • Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景?

面试官心理分析

其实面试官主要是想看看:编程

  • 第一,你知不知道大家系统里为何要用消息队列这个东西?
    很多候选人,说本身项目里用了 Redis、MQ,可是其实他并不知道本身为何要用这个东西。其实说白了,就是为了用而用,或者是别人设计的架构,他从头至尾都没思考过。
    没有对本身的架构问过为何的人,必定是平时没有思考的人,面试官对这类候选人印象一般很很差。由于面试官担忧你进了团队以后只会木头木脑的干呆活儿,不会本身思考。浏览器

  • 第二,你既然用了消息队列这个东西,你知不知道用了有什么好处&坏处?
    你要是没考虑过这个,那你盲目弄个 MQ 进系统里,后面出了问题你是否是就本身溜了给公司留坑?你要是没考虑过引入一个技术可能存在的弊端和风险,面试官把这类候选人招进来了,基本可能就是挖坑型选手。就怕你干 1 年挖一堆坑,本身跳槽了,给公司留下无穷后患。架构

  • 第三,既然你用了 MQ,多是某一种 MQ,那么你当时作没作过调研?
    你别傻乎乎的本身拍脑壳看我的喜爱就瞎用了一个 MQ,好比 Kafka,甚至都从没调研过业界流行的 MQ 到底有哪几种。每个 MQ 的优势和缺点是什么。每个 MQ 没有绝对的好坏,可是就是看用在哪一个场景能够扬长避短,利用其优点,规避其劣势。
    若是是一个不考虑技术选型的候选人招进了团队,leader 交给他一个任务,去设计个什么系统,他在里面用一些技术,可能都没考虑过选型,最后选的技术可能并不必定合适,同样是留坑。并发

面试题剖析

1. 为何使用消息队列?

其实就是问问你消息队列都有哪些使用场景,而后你项目里具体是什么场景,说说你在这个场景里用消息队列是什么?异步

面试官问你这个问题,指望的一个回答是说,大家公司有个什么业务场景,这个业务场景有个什么技术挑战,若是不用 MQ 可能会很麻烦,可是你如今用了 MQ 以后带给了你不少的好处。分布式

先说一下消息队列常见的使用场景吧,其实场景有不少,可是比较核心的有 3 个:解耦、异步、削峰。svg

解耦
看这么个场景。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 系统就会快速将积压的消息给解决掉。

2. 消息队列有什么优缺点?

优势上面已经说了,就是在特殊场景下有其对应的好处,解耦、异步、削峰。

缺点有如下几个:

系统可用性下降
系统引入的外部依赖越多,越容易挂掉。原本你就是 A 系统调用 BCD 三个系统的接口就行了,人 ABCD 四个系统好好的,没啥问题,你偏加个 MQ 进来,万一 MQ 挂了咋整,MQ 一挂,整套系统崩溃的,你不就完了?如何保证消息队列的高可用?

系统复杂度提升
硬生生加个 MQ 进来,你怎么保证消息没有重复消费?怎么处理消息丢失的状况?怎么保证消息传递的顺序性?头大头大,问题一大堆,痛苦不已。

一致性问题
A 系统处理完了直接返回成功了,人都觉得你这个请求就成功了;可是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。

因此消息队列实际是一种很是复杂的架构,你引入它有不少好处,可是也得针对它带来的坏处作各类额外的技术方案和架构来规避掉,作好以后,你会发现,妈呀,系统复杂度提高了一个数量级,也许是复杂了 10 倍。可是关键时刻,用,仍是得用的。

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

特性 ActiveMQ RabbitMQ RocketMQ Kafka
单机吞吐量 万级,比 RocketMQ、Kafka 低一个数量级 同 ActiveMQ 10 万级,支撑高吞吐 10 万级,高吞吐,通常配合大数据类的系统来进行实时数据计算、日志采集等场景
topic 数量对吞吐量的影响 topic 能够达到几百/几千的级别,吞吐量会有较小幅度的降低,这是 RocketMQ 的一大优点,在同等机器下,能够支撑大量的 topic topic 从几十到几百个时候,吞吐量会大幅度降低,在同等机器下,Kafka 尽可能保证 topic 数量不要过多,若是要支撑大规模的 topic,须要增长更多的机器资源
时效性 ms 级 微秒级,这是 RabbitMQ 的一大特色,延迟最低 ms 级 延迟在 ms 级之内
可用性 高,基于主从架构实现高可用 同 ActiveMQ 很是高,分布式架构 很是高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会致使不可用
消息可靠性 有较低的几率丢失数据 基本不丢 通过参数优化配置,能够作到 0 丢失 同 RocketMQ
功能支持 MQ 领域的功能极其完备 基于 erlang 开发,并发能力很强,性能极好,延时很低 MQ 功能较为完善,仍是分布式的,扩展性好 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用

综上,各类对比以后,有以下建议:

通常的业务系统要引入 MQ,最先你们都用 ActiveMQ,可是如今确实你们用的很少了,没通过大规模吞吐量场景的验证,社区也不是很活跃,因此你们仍是算了吧,我我的不推荐用这个了;

后来你们开始用 RabbitMQ,可是确实 erlang 语言阻止了大量的 Java 工程师去深刻研究和掌控它,对公司而言,几乎处于不可控的状态,可是确实人家是开源的,比较稳定的支持,活跃度也高;

不过如今确实愈来愈多的公司会去用 RocketMQ,确实很不错,毕竟是阿里出品,但社区可能有忽然黄掉的风险(目前 RocketMQ 已捐给 Apache,但 GitHub 上的活跃度其实不算高)对本身公司技术实力有绝对自信的,推荐用 RocketMQ,不然回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄。

因此中小型公司,技术实力较为通常,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。

若是是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,况且几乎是全世界这个领域的事实性规范。

(想自学习编程的小伙伴请搜索圈T社区,更多行业相关资讯更有行业相关免费视频教程。彻底免费哦!)