首页 > 编程知识 正文

为什么要使用消息队列,mq面试题及答案

时间:2023-05-04 05:37:06 阅读:147418 作者:1426

http://www.Sina.com/http://www.Sina.com /相关视频参考(来自电源节点) 3359 www.bilibili.com/video/bv1a P4 y1 D7 tu

下载相关资料: http://www.bjpowernode.com/csdn

几种常见的MQ其实就是问问消息队列中有什么使用场景。 而且,在你的项目中具体有什么场景? 这个场景中使用消息队列的是什么?

面试官问你这个问题,期待的答案之一是,你们公司有什么业务场景? 这个业务场景有什么技术挑战? 不使用MQ可能会很辛苦,但你现在使用MQ带来了很多好处。

首先,让我来说明消息队列中常见的使用场景。 虽然有很多真实的场景,但核心有三个:

面试题

为什么使用消息队列?

在这种情况下,a系统与其他各种乱七八糟的系统严重耦合,a系统生成相对重要的数据,许多系统需要a系统发送该数据。 a系统必须始终考虑BCDE的四个系统。 如果挂断了该怎么办? 是要重新发送还是保存信息? 头发白了哦!

使用MQ时,a系统生成数据并将其发送到MQ中,哪个系统需要数据自己消耗在MQ中。 新系统需要数据时,直接从MQ消耗即可; 如果一个系统不再需要这个数据,取消MQ消息的消耗就可以了。 这样,a系统不需要考虑向谁发送数据,也不需要维护这个代码,也不需要考虑人是否调用成功、是否失败等。

解耦、异步、削峰。

需要考虑一下场景一:A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也要这个数据呢?那如果 C 系统现在不需要了呢?A 系统负责人几乎崩溃......负责的系统是否有类似的场景。 也就是说,一个系统或模块调用了多个系统或模块。 相互的调用很复杂,维护起来很辛苦。 但是,其实这个调用不需要直接同步调用接口,也可以用MQ异步解绑定,需要考虑在你的项目中,是否可以用这个MQ解系统的绑定。 简历上出现这个东西,用MQ解耦。

总结:通过一个 MQ,Pub/Sub 发布订阅消息这么一个模型,A 系统就跟其它系统彻底解耦了。

在一般的互联网类企业中,对于用户的直接操作,每次要求都必须在200 ms以内完成,要求用户几乎看不到。

使用MQ时,a系统会连续向MQ队列发送三条消息。 假设时间需要5ms,a系统从收到一个请求到回复用户,总时间为3 5=8ms,对用户来说,其实只需点击按钮,8ms后直接返回,很清爽。 网站做得很好,真快!

面试技巧:

请求到 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 系统写库失败了,咋整?你这数据就不一致了。

如何选择MQ?

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

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

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

所以中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。

怎么保证消息没有重复消费?

1.如果是拿这个消息做数据库insert操作(事实上update和delete重复也不影响)给这个消息做一个唯一主键,那么就算出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据。

2.当拿到这个消息做redis的set的操作,那就容易了,不用解决,因为你无论set几次结果都是一样的,set操作本来就算幂等操作。

3.如果上面两种情况还不行,准备一个第三方存储,来做消费记录。以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以K-V形式写入redis。那消费者开始消费前,先去redis中查询有没消费记录即可。

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