当前位置: 首页 > 科技观察

面试官问我:什么是消息队列?什么场景需要他?使用时会出现什么问题?

时间:2023-03-22 14:11:41 科技观察

采访开始,一个英俊的中年男子穿着格子衬衫,拿着一个划痕的Mac走向你,看着他闪亮的脑袋,心想他一定是尼玛的顶级架构师!但我们看过敖丙这个暖男系列,充满了诗情画意,并不空洞。小伙子之前问了你那么多关于Redis的事情。你不仅回答的很流利,而且还可以很流利的解释每个场景的解决方案和优缺点。你看过敖丙写的《我们一起进大厂》系列吗?震惊!!!老师,你怎么知道,我看他的系列就停不下来了。呵呵,Redis没打扰你,不过我要是问一个新的技术栈,只怕难不倒你吧?请问你,你在项目中用过消息队列吗?为什么要使用消息队列?噗,这也叫问题?别人用了我就不能用了吗?别人用,我就用,为了用而用。你就在心里嘀咕,别说了,没拿到offer就别说了,敖丙那个没心没肺的人教我说的!面试官你好:我们公司业务量很小,所以直接单机搞定,但是后面业务量不断扩大,采用微服务的设计思想和分布式部署方式,所以拆了很多服务已被划分。随着体量的增加,业务场景越来越复杂,很多场景的技术栈和中间件不够用,对系统的友好度也有所下降。最后,完成了很多技术。对于选型工作,我们决定引入消息队列中间件。哦?您提到业务场景越来越复杂,请问您在哪些场景下使用了消息队列?好吧,我从三个方面说说我使用的场景。提示:这三个场景也是消息队列的经典场景。您基本上需要熟悉它们。说到消息队列,肯定会想到异步、削峰、解耦、条件反射。异步:在我们之前的场景中,有很多步骤需要在一个进程中完成。比如我的订单系统,我们的业务本来就很简单,下单付款,流程就结束了。.但是后来一个产品经理来了,建立了一个优惠券系统。OK,问题不大,扣券的过程中多了100ms。后来产品经理灵光一现,说我们可以做一个积分系统,没关系,这个过程中多了200ms来增加或减少积分。后来隔壁的产品老王说:下单成功后,我们会发短信给用户,就100ms以内发短信吧。在那之后。..(敖丙,你没完没了!!!)反正流程有点像这样↓可以看到只加了三个,我可以肯定的告诉你,真正的下单流程涉及10多个系统(主流电子商务),越大越多。如果这个环节一直这样下去,那需要很长时间。用户需要几十秒才能发现我买了东西。垃圾电商我是不会买的,不过要是像冰溪溪一样便宜,真的很好吃!但是我们公司没有西溪的经济实力,只能优化系统。小提示:我所在的老牌电商要求所有接口的Rt(ResponseTime响应时间)在200ms以内,超过这个的都做优化。我现在负责的系统QPS也是9W+,就算网络集群动摇,也可能炒锅。RT基本要求在50ms以内。大家感受一下这个QPS。嗯,是的,链接长了会慢,请问怎么解决呢?如果链接很长,会很慢,但是我们发现上面的过程其实是可以同时进行的。支付成功后,我可以在验证优惠券的同时增加或减少积分,同时还可以发短信。.正常流程我们实现不了,怎么办,异步。对比一下,你有没有发现,用户知道下单成功最多只需要100毫秒。至于你几秒后给他发的短信,他根本不在乎吧?小子,我打断你,你说异步,那我用线程和线程池来做,不是一样的吗?喂,面试官,你别着急,我待会再说,骚等等。解耦:既然面试官问了这个问题,那我给大家说说为什么我们不能用线程来做,因为如果用线程来做,还要写代码吗?你有个下单流程,你扣积分,扣优惠券,发短信,扣库存。..等那么多服务调用那么多接口,每增加一个就需要调用一个接口,然后重新发布系统。写一两次还好,写多了就说:我不干了!而且如果都写在一起,不仅仅是耦合的问题,出了问题排查起来也很麻烦。如果过程中任何一个环节出现问题,都可能影响到其他环节。朋友说我每一个进程都试试catch,相信我,千万别做,这种代码就像一颗定时炸弹💣,你不知道它什么时候爆炸,如果你不做平时会爆炸但是活动的时候会爆炸,会报P0故障收拾好书包早点回家过年。提示:P0-PN是各大互联网公司经常使用的一种判断事故级别的机制,P0是最高级别。但是如果使用消息队列,耦合的问题就迎刃而解了。哦,帅兵怎么说?并且听我说:你下单后,你告诉其他系统你支付成功了,他们收到后会处理。你只需要走你自己的流程,发送你自己的消息,那后面连接什么系统就简单了,订阅你发送的支付成功消息就可以了,支付成功我会监控。那么你的过程就结束了,你不在乎别人成功与否吗?比如下单了,没有加积分,没有扣优惠券怎么办?问题是个好问题,但没必要考虑。业务系统本身由自己的开发人员维护。如果你的扣分失败,我下单有什么关系?只需照顾好自己的订购系统即可。提示:话是这么说的,但这其实是使用消息队列的一个缺点,涉及到分布式事务的知识点,下面会提到。削峰:以我上一期写的秒杀为例(暗示新同学看了我上一期),平时你的流量很低,但是00:00想秒杀的时候,流量就冲了疯狂的是,你的服务器、Redis、MySQL的承载能力各不相同。如果直接按照命??令接收所有流量,肯定有问题,直接挂掉。那么该怎么办?简单,把请求放到队列里,然后至于每秒消耗多少请求,就看你服务器的处理能力了。如果你能处理5000QPS,你可以消耗这么多。它可能比平时慢,但不会挂起服务器。当流量高峰下来,您的服务将不再有压力。看看阿里巴巴的双十一12:00,那么多流量瞬间涌入,是不是有时会变慢,但是人家不挂,还是降级给你友情提醒页面,等高峰过后,会有另一个他是个好人。对于这个数字,一个服务的流量是有意增加的。对于这个数字,一个服务的流量是有意增加的。听你说这么火,反正有好处。那我问你,使用消息队列有什么问题吗?哎,看过我之前写的文章的都知道,我常说的是技术是一把双刃剑!没错,面试官,我用他是因为他给我们带来了很多好处,但是用了之后,问题接踵而至。同样的暖男,我也从三点介绍了他的主要缺点:系统复杂度是一个系统,其实很简单,我可以随便写代码,但是现在你凭空接一个中间件,我是不是应该考虑维护一下,以及在使用过程中需要考虑各种问题吗,比如消息的重复消费,消息的丢失,消息的顺序消费等等,反正用了之后会很烦。插一句,能否介绍一下上面的问题(重复消费、消息丢失、顺序消费)以及如何解决?**不要!**我已经说了敖丙下一章会写什么?其实我不想写在这里,因为我不是暖男。这三个问题我都想过,都是MQ的关键问题。单独拿一个就是一篇文章。长度太长。我会在下一章一一介绍。一遍又一遍地。数据一致性其实是分布式服务本身就存在的问题,不仅仅是消息队列的问题,这里提到是因为使用消息队列的问题会更严重。开头说了,你点的服务保证你的逻辑处理成功,你发消息成功,但是优惠券系统,积分系统等等系统那么多,你不管他们有没有成功还是失败?我说只要保证你的业务数据是正确的就可以了。其实说它像一个没有结构的没心没肺的人,是一种比较不负责任的说法。这样,你的路就会越来越窄。只有所有的服务都成功了,这一次才能下单成功,那么如何保证数据的一致性呢?分布式事务:下单、优惠券、积分。..这与将它们全部放在一个事务中是一样的。要想成功就要一起成功,要失败就要一起失败。提示:分布式事务在互联网公司中确实很常见,这里就不大篇幅介绍了,以后再说。可用性你系统本身没有问题,但是现在突然连接一个中间件放在那里,挂了怎么办?我下单MQ暂停了,优惠券不扣,积分不扣。这可不是干掉一个程序员就能搞定的,感觉就是干掉一块。至于如何保证高可用,那句话这里就不说了。以后再写,就像写Redis一样。敖丙你放心,我可不是没良心的人,我一定会对你负责的。喜欢!我看不出来,你有东西,那我问你,你是怎么选技术的?目前市场上主流的消息队列中间件主要有Kafka、ActiveMQ、RabbitMQ、rocketMQ等。但是敖丙,我想说的是,ActiveMQ和RabbitMQ因为吞吐量和GitHub的社区活跃度,在各大互联网公司基本消失了。是的,但是越来越多的公司更喜欢rocketMQ这样的消息中间件。Kafka和rocketMQ一直都在各自的专业领域大放异彩,但写这篇文章的时候,请教了蚂蚁金服、字节跳动和美团的朋友。好像每个人用的东西都不一样,应该是中间的软件有可能是修改过的,也有可能是自己开发的,大部分都不是开源的。就像我们公司是基于Kafka和rocketMQ的优点自研的消息队列中间件,吞吐量、可靠性、时效性都非常可观。让我们回到主题。我就用网上找的对比图,让大家看看差距在哪里:其实一下子就能看出差距。以吞吐量为例。早期比较活跃的ActiveMQ和RabbitMQ,基本上不是同一个竞争对手,吞吐量在这个大数据时代真的很重要。比如突然爆出一个超级热门的新闻,你的app有上亿的注册用户。你必须想办法在第一时间把所有的消息推送给每个人。如果你没有高吞吐量的消息队列中间件,你能用什么?推?此外,大量的这些用户进来观看您的新闻,从而产生了一系列附带流量。你如何处理这些数据?在很多场景下,离开消息队列基本上是不可持续的。就部署方式而言,前两者不如后两个天生的分布式架构兄弟。它们都是高可用的分布式架构,数据多副本的数据也可以做到零丢失。再说说中间件RabbitMQ,其实还可以,但是这东西的开发语言其实是erlang。我敢说,绝大部分工程师肯定不会为了一个中间件去刻意去学一门语言。开发和维护成本超乎你的想象,如果有问题,要检查很长时间。至于rocketMQ(阿里开源),git活跃度还不错。基本上你自己push自己的bug,确认有什么问题,阿里大佬都会尽量和你一起解答修复。这是我个人推荐的。他的架构设计是真实的一个RPC框架,也是阿里开源的。和(Dubbo)很像,可能是因为老师来自同一个学校。提示:Dubbo等我写RPC,我会详细介绍。我把卡夫卡放在最后,说你应该知道压轴的是大哥。在大数据领域,公司的日志采集、实时计算等场景,都离不开他。他基本上是世界级的领导者。消息队列基准已启动。以上只是我个人的一些看法。真正的选择还有待深入研究。不然你们公司的UV一天1000。如果你告诉我你要用Kafka,我只能说你吃饱了。记住,没有最好的技术,只有最合适的技术,不要为了使用它而使用它。采访结束了,小伙子不错,分析到位了,那大家记得下期聊消息队列的高可用、重复消费、消息丢失、消息顺序、分布式事务等问题吗?嗯,不错的面试官,就是不知道能不能一口气说完。毕竟敖丙还没有开始写作,读者可能会白嫖,动力未必够。嗯,这是个问题,不过看的都是有才华的人,一定会为你竖起大拇指👍!我想是这样。总结一下消息队列的基础知识,先介绍这么多。消息队列和我之前面试写的Redis基本一样。面试的思路还是一样的,whatisandwhy,就是要知道为什么用它,用它有什么好处,有什么坑。面试官不喜欢那些只会用的人。如果您只使用的天线有问题怎么办?你在旁边拜佛吗?我是敖丙,一个生活在互联网上的工具人。