本文主要讨论以下面试题。为什么要使用消息队列?消息队列的优点和缺点是什么?Kafka、ActiveMQ、RabbitMQ、RocketMQ的优缺点是什么?面试官的心理分析其实面试官主要是想看:第一,你知道你的系统为什么要用消息队列吗?很多应聘者说他们在项目中使用了Redis和MQ,但实际上他们并不知道为什么要使用它们。其实说白了就是为了好用,或者说是别人设计的结构,他从始至终都没有想过。没有问过自己结构为什么的人,一定是平时不会去想的人。面试官通常对这样的应聘者印象不好。因为面试官担心你加入团队后只会干枯燥的工作,不会自己思考。二、既然你用过消息队列,你知道使用它的优缺点吗?如果你没有考虑到这一点,那你就一味的把MQ放到系统里,万一以后出了什么问题,你自己溜走,给公司留下空子?如果没有考虑过引进一项技术可能带来的弊端和风险,招聘这样的应聘者的面试官可能基本上就是个挖坑人。就怕干了一年坑多了,就跳槽了,给公司留下后患无穷。第三,你既然用了MQ,可能是某种MQ,当时有没有研究一下?别傻傻的用Kafka这样的MQ,因为拍脑袋看个人喜好。业界流行的MQ类型,你根本就没有调查过。每个MQ的优点和缺点是什么。每一个MQ都没有绝对的好坏,而是看它用在哪个场景,扬长避短,扬长避短。如果把一个不考虑技术选型的应聘者招进团队,领导给他一个任务,设计一个系统。他在里面使用了一些技术,但他可能没有考虑过选型。最后的技术不一定适合,一样是留个坑。先说说消息队列的常见使用场景。其实场景有很多,但最核心的是三个:解耦、异步、调峰。脱钩看到这样的场景。系统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毫秒内完成,用户几乎感觉不到。如果使用MQ,A系统连续向MQ队列发送3条消息。如果用了5ms,系统A从接受请求到返回响应给用户用了3+5=8ms。对于用户来说,其实感觉就是点击一个按钮,8ms后直接返回,爽!该网站做得很好,速度也很快!调峰期间,每天0:00-12:00,系统A平静,每秒并发请求数只有50个,结果每次12:00-13:00,A系统的请求数每秒并发请求突然增加到5k+。但是系统是直接基于MySQL的,大量的请求涌入MySQL,每秒在MySQL上执行约5k条SQL。对于一般的MySQL来说,每秒处理2k个请求差不多就够了。如果请求达到每秒5k,MySQL可能会直接被kill掉,导致系统崩溃,用户将无法再使用系统。但是高峰期一过,下午就会变成低峰期。网站同时操作的用户可能只有10000个,每秒的请求数可能只有50个请求,对整个系统几乎没有影响。压力。如果使用MQ,每秒有5k个请求写入MQ,系统A每秒最多可以处理2k个请求,因为MySQL每秒最多可以处理2k个请求。系统A从MQ中慢慢拉取请求,每秒拉取2k个请求,不超过每秒能处理的最大请求数就可以了。这样即使在高峰期,系统A也永远不会挂掉。但是,MQ每秒有5k个请求进来,只有2k个请求出去。导致在中午高峰期(1小时),MQ中可能会积压几十万甚至上百万的请求。这个短暂的高峰期的积压是可以的,因为高峰期过后,每秒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是行业标准,绝对没问题,社区很活跃,永远不会黄,更何况几乎是一个全世界该领域的事实规范。
