首页 > 编程知识 正文

dubbo原理面试题(redis面试题)

时间:2023-05-06 21:20:45 阅读:101354 作者:4794

面试问题

为什么要使用消息队列?

消息队列的优缺点是什么?

卡夫卡、ActiveMQ、RabbitMQ、RocketMQ之间有什么区别,适合什么场景?

采访者心理分析

其实面试官主要想看到的是:

首先,您知道为什么在系统中使用消息队列吗?很多考生说他们在项目中使用了Redis和MQ,但实际上他并不知道自己为什么要用。其实说白了就是为了使用,或者是别人设计的架构。他从头到尾都没想过这件事。没有问过自己结构为什么的人,一定是平时不思考的人,面试官通常对这样的应聘者印象不好。因为面试官担心你加入团队后,只会做枯燥的工作,不会为自己着想。

第二,既然你使用了消息队列,你知道它有什么优点和缺点吗?如果你没有考虑到这一点,那么你就盲目地把一个MQ弄进系统,如果以后出了问题,你是不是就这么溜走了,给公司留了个窟窿?如果你还没有考虑到引进一项技术可能存在的劣势和风险,面试官会招聘这样的应聘者,他们基本上都是挖坑的。恐怕挖一年一堆坑,换个工作,离开公司麻烦无穷。

第三,既然你用了MQ,可能是某种MQ,那你当时有没有做什么研究?不要拍着脑袋看个人喜好,忽悠自己用一个MQ,比如卡夫卡。你甚至从来没有调查过什么类型的MQ在行业中流行。每个MQ的优缺点是什么?每一个MQ都不是绝对的好或者坏,而是看它可以用在哪个场景上,来利用它的优点,避免它的缺点。如果一个不考虑技术选择的候选人被招募到团队中,领导者会给他一个设计系统的任务。他在里面使用了一些技术,可能没有考虑过技术的选择。最后选择的技术可能不适合,但同样是留洞。

面试问题分析

为什么要使用消息队列?

其实我就是想问一下消息队列中使用了哪些场景,然后你的项目中具体有哪些场景,告诉我你在这个场景中使用了哪些消息队列?

当面试官问你这个问题时,预期的答案之一是,你的公司有什么业务场景,这个业务场景有什么技术挑战?如果不使用MQ,可能会很麻烦,但是现在使用MQ之后会给你带来很多好处。

我们先来说说消息队列的常见使用场景。实际上,有很多场景,但有三个核心场景:解耦、异步和削峰。

退耦

看这一幕。一个系统向BCD三个系统发送数据,并通过接口调用发送。如果e系统也想要这些数据呢?如果现在不需要C系统怎么办?系统A负责人差点崩溃。

在这种场景下,系统A与其他杂乱的系统严重耦合。系统A产生一个关键的数据,很多系统需要系统A发送这个数据。一个系统应该始终考虑BCDE四大系统。失败了怎么办?您想重新发送吗?您想保存消息吗?我的头发是白色的!

如果使用MQ,系统A会生成一段数据并发送给MQ,MQ需要系统自己在MQ中消费数据。如果新系统需要数据,可以直接从MQ消费;如果某个系统不需要这些数据,就取消MQ消息的消耗。这样,系统A就不需要考虑向谁发送数据,维护这个代码,也不需要考虑其他人是否调用成功或者超时失败。

总结:通过MQ、Pub/Sub发布订阅消息的模型,系统A与其他系统完全解耦。

面试技巧:需要考虑你负责的系统中是否有类似的场景,即一个系统或者一个模块调用多个系统或者模块,相互调用非常复杂,维护起来也很麻烦。但实际上,这个调用不需要直接同步调用接口。如果用MQ异步解耦,那就可以了。您需要考虑在您的项目中是否可以使用MQ来解耦系统。在简历中反映这个东西,用MQ作为解耦。

异步的

让我们看看另一个场景。系统A收到请求时,需要在本地写库,在BCD三系统中也需要在本地写库。本地写库需要3ms,BCD三个系统写库分别需要300ms、450ms、200ms。请求的最终总延迟为3 300 450 200=953ms,接近1秒。用户感觉有事情正在发生。太慢了。用户通过浏览器发起请求,等待1s,这几乎是不可接受的。

6aca17b19.png?from=pc">

一般互联网类的企业,对于用户直接的操作,一般要求是每个请求都必须在 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 倍。但是关键时刻,用,还是得用的。

综上,各种对比之后,有如下建议:

一般的业务系统要引入 MQ,最早大家都用 ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,所以大家还是算了吧,我个人不推荐用这个了;

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

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

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

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

分享我自己的一个Java后端技术公众号,(Javasuiyue)

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。