首页 > 其他分享 >详解MQ消息队列及四大主流MQ的优缺点

详解MQ消息队列及四大主流MQ的优缺点

时间:2024-02-23 09:01:09浏览次数:23  
标签:场景 请求 队列 系统 优缺点 并发 详解 MQ JD

前言

近期有了想跳槽的打算,所以自己想巩固一下自己的技术,想了解一些面试比较容易加分的项,近期准备深入研究一下Redis和MQ这两样,这总体上都是为了解决服务器并发的原因,刚翻到了一篇有关于MQ的,觉得写得特别好,特此记录一下,也算是为了加深自己的印象。

面试题切入

  • 1、为什么要使用MQ
  • 2、消息队列有什么优点和缺点
  • 3、kafka、ActiveMQ、RabbitMQ、RocketMQ有什么区别

面试官心理分析

首先,你们系统里面为什么要用MQ

不少去面试的人,都知道自己以前项目里面用过MQ、Redis,但是为什么用这个,却不知道,这种人说白了就是为了用而用,又或者这个框架就是别人设计的,他自己都没了解过里面的东西,自然也不知道为什么要用。如果面试的时候面试官问你这种问题你答不上来,可能已经被pass百分之三十了,面试官通常对这种人印象很不好,他怕你进了公司只会埋头苦干,不懂得自己思考。

第二,你既然用了MQ,那你知不知道MQ有什么好处和坏处

如果没考虑过这个问题一定要慎重回答,因为你没考虑过这个,盲目的弄个MQ进系统,当下的问题可能是解决了,但万一后面出了问题不是给公司留坑吗,面试官就怕这样的人,招进来干了一年,自己跳槽了,给系统挖一堆坑,留下无穷祸患。

第三,既然你用了MQ,比如其中一种MQ,那你当时做没做过调研

别看别人用了MQ,咦,感觉挺好的,就自己瞎弄了一个,根本没考虑过MQ的选型,比如kafka,每个MQ并没有绝对的好处和坏处,现在业界流行的MQ各有各的好处,各有各的坏处,你要做的就是扬长避短,挑选最适合自己系统的MQ。

面试题剖析

①为什么要使用MQ

其实面试官问你这个问题就是想知道,你们公司有个什么样的业务场景,这个业务场景有个什么技术挑战,如果不用MQ可能会比较麻烦,包括现在用了MQ以后有哪些好处等等。先说一下MQ常见的使用场景吧,MQ的使用场景有很多,但是比较核心的就是:解耦、异步、削锋。

系统解耦

首先举例下面这个场景,现有ABCDE五个系统,最初的时候BCD三个系统都要调用A系统的接口获取数据,一切都很正常,但是突然,D系统说:我不要了,你不用给我传数据了,A系统无奈,只能修改代码,将调用D系统的代码删除,这时候还没删除呢,E系统发送了请求,但是A系统这时候还没处理完D系统的请求,A系统卒!!!彻底崩溃。

看下图↓↓↓↓↓↓↓↓↓↓↓

 

 

上述场景中,BCDE都需要用到A系统提供的数据,A系统跟其他四个系统严重耦合,需要时时刻刻考虑其他四个系统要是挂了怎么办,需不需要重新发送数据给他们,这个时候的A系统内心是崩溃的。

但是如果使用了MQ之后 ,A系统的数据只需要放到MQ里面,其他的系统想请求获取数据只需要去MQ里面消费即可,如果突然不想请求了,就取消对MQ的消费就行了,A系统根本不需要考虑给谁去响应这个数据,也不需要去维护代码,也不用考虑其他系统是否调用成功,失败超时等情况。

详细看下图↓↓↓↓↓↓↓↓

 

 

总结:通过MQ发布订阅消息的模型,A系统就成功的跟其他系统解耦了。

面试技巧:你需要思考一下,在你自己的系统里面有没有类似的情况,一个系统或者模块,调用了多个系统或者模块,它们互相之间的调用非常复杂,并且维护起来很麻烦,但其实这个调用是不需要直接同步调用接口的,如果用MQ给它异步化解耦也是可以的,你就需要思考在你的项目里,是不是可以用MQ给它进行系统的解耦,可以自己组织一下语言回答。

异步调用

场景二,还是ABCD四个系统,A系统收到一个请求,需要在自己本地写库,还需要往BCD三个系统写库,A系统自己写本地库需要3ms,往其他系统写库相对较慢,B系统200ms ,C系统350ms,D系统400ms,这样算起来,整个功能从请求到响应的时间为3ms+200ms+350ms+400ms=953ms,接近一秒,对于用户来说,点个按钮要等这么长时间,基本是无法接受的,侧面也反映出这家研发人员技术不咋地。

详情如下图↓↓↓↓↓↓

 

 

一般的互联网企业,对于用户请求响应的时间要求在100ms-200ms之间,这样,用户的眼睛存在视觉暂停现象,用户响应时间在此范围内就可以了,所以上面的现象是不可取的。

如果用了MQ,用户发送请求到A系统耗时3ms,A系统发送三条消息到MQ,假如耗时5ms,用户从发送请求到相应3ms+5ms=8ms,仅用了8ms,用户的体验非常好。

 

 

流量削峰

场景三,这次举个实例吧,也是近期发生的,我们都知道 ,2020年爆发的这场新冠病毒,导致各大线上商城APP里面的口罩被抢购一空,在这种情况下,JD商城开启了一场每晚八点的抢购3Q口罩的活动,每天下午三点进行预约,晚上八点抢购,从JD商城刚上线这个活动,我连续抢了近一个周,也算是见证了一个百万并发量系统从出现问题到完善的一个过程,最初第一天,我抢购的时候,一百多万预约,到八点抢购估计也能有百万的并发量,可是第一天,到八点我抢的时候,由于并发量太高,直接把JD服务器弄崩了,直接报了异常,可能JD在上线这个活动的时候也没能够想到会有那么高的并发,打了一个猝不及防,但是这只是在前一两天出现报异常的情况,后面却没有再出现异常信息,到后来再抢购只是响应的时间变得很慢,但是JD系统并没有崩溃,这种情况下一般就是用了MQ(或者之前用了MQ,这次换了个吞吐量级别更高的MQ),也正是利用了MQ的三大好处之一——削峰。

JD系统每天0—19点,系统风平浪静,结果一到八点抢购的时候,每秒并发达到百万,假设JD数据库没秒能处理1.5w条并发请求(并非实际数据,主要为了举例),到八点抢购的时候,每秒并发百万,这直接导致系统异常,但是八点一过,可能也就几万用户在线操作,每秒的请求可能也就几百条,对整个系统毫无压力。

 

 

如果使用了MQ,每秒百万个请求写入MQ,因为JD系统每秒能处理1W+的请求,JD系统处理完然后再去MQ里面,再拉取1W+的请求处理,每次不要超过自己能处理的最大请求量就ok,这样下来,等到八点高峰期的时候,系统也不会挂掉,但是近一个小时内,系统处理请求的速度是肯定赶不上用户的并发请求的,所以都会积压在MQ中,甚至可能积压千万条,但是高峰期过后,每秒只会有一千多的并发请求进入MQ,但是JD系统还是会以每秒1W+的速度处理请求,所以高峰期一过,JD系统会很快消化掉积压在MQ的请求,在用户那边可能也就是等的时间长一点,但是绝对不会让系统挂掉。

 

 

消息队列的优缺点


优点
上面已经说过了,系统解耦,异步调用,流量削峰。

缺点

①系统可用性降低: 系统引入的外部依赖越多,系统要面对的风险越高,拿场景一来说,本来ABCD四个系统配合的好好的,没啥问题,但是你偏要弄个MQ进来插一脚,虽然好处挺多,但是万一MQ挂掉了呢,那样你系统不也就挂掉了。

②系统复杂程度提高: 非要加个MQ进来,如何保证没有重复消费呢?如何处理消息丢失的情况?怎么保证消息传递的顺序?问题太多。

③一致性的问题: A系统处理完再传递给MQ就直接返回成功了,用户以为你这个请求成功了,但是,如果在BCD的系统里,BC两个系统写库成功,D系统写库失败了怎么办,这样就导致数据不一致了。所以。消息队列其实是一套非常复杂的架构,你在享受MQ带来的好处的同时,也要做各种技术方案把MQ带来的一系列的问题解决掉,等一切都做好之后,系统的复杂程度硬生生提高了一个等级。

四大主流MQ(kafka、ActiveMQ、RabbitMQ、RocketMQ)各自的优缺点

目前业界四大主流的MQ有kafka、ActiveMQ、RabbitMQ、RocketMQ。其他的MQ也有,不过比较冷门。就不用多说了,画个表就明白了。↓↓↓↓↓↓↓↓

 

 

 

 


综上所述,各种对比之后,我个人倾向于是:

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

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

不过现在确实越来越多的公司,会去用RocketMQ,确实很不错,但是我提醒一下自己想好社区万一突然黄掉的风险,对自己公司技术实力有绝对自信的,我推荐用RocketMQ,否则回去老老实实用RabbitMQ吧,人是活跃开源社区,绝对不会黄

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

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

标签:场景,请求,队列,系统,优缺点,并发,详解,MQ,JD
From: https://www.cnblogs.com/shujuyr/p/18028570

相关文章

  • C++ 第四节课 C和C++指针的区别 C的宏函数和C++内联函数的优缺点
    #include<iostream>//定义一个宏函数#defineADD(x,y)x+y;//宏函数具有速度快等特点但是写代码有些业务比较繁琐,所以C++中使用了内联函数优化//在定义函数前面添加一个inline把这个函数变成内联函数inlineintmax(intx,inty){returnx>y?x:y;}usi......
  • Object— Object.defineProperty()(详解、原理、作用、使用场景、使用方式)
    一.Object.defineProperty()详解Object.defineProperty()是JavaScript中用于定义或修改对象的属性的方法,可以控制属性的特性(如可枚举性、可配置性、可写性等)。Object.defineProperty()方法的语法如下:Object.defineProperty(obj,prop,descriptor)obj:要在其上定义属性......
  • Java 构造函数与修饰符详解:初始化对象与控制权限
    Java构造函数Java构造函数是一种特殊的类方法,用于在创建对象时初始化对象的属性。它与类名相同,并且没有返回值类型。构造函数的作用:为对象的属性设置初始值执行必要的初始化操作提供创建对象的多种方式构造函数的类型:默认构造函数:无参数的构造函数,如果用户没有明......
  • CSS Border Bottom常用属性详解
    原文链接:https://www.python100.com/html/90865.html一、border-bottom的基本使用border-bottom:单位边框样式颜色;border-bottom是css中用来设置底部边框的属性。border-bottom的属性值包括三个,分别是:边框宽度(单位),边框样式(solid、dotted、dashed等)和边框颜色(十六进制......
  • 多线程系列(六) -等待和通知模型详解
    一、简介在之前的线程系列文章中,我们介绍了synchronized和volatile关键字,使用它能解决线程同步的问题,但是它们无法解决线程之间协调和通信的问题。举个简单的例子,比如线程A负责将int型变量i值累加操作到10000,然后通知线程B负责把结果打印出来。这个怎么实现呢?其中一个......
  • shiro 整合 spring 实战及源码详解
    序言前面我们学习了如下内容:5分钟入门shiro安全框架实战笔记shiro整合spring实战及源码详解相信大家对于shiro已经有了最基本的认识,这一节我们一起来学习写如何将shiro与spring进行整合。spring整合maven依赖<dependencies><dependency><group......
  • Qt 图例类QLegend详解
    概述在Qt绘制图表时,图例并不是由QChart类所管理的,而是交给单独的QLegend类。QLegend类负责图例的绘制(包括颜色、线型、字体等),它与图表类QChart的关系是attach和detach。实例参考官方实例:X:\Qt\Qt5.9.0\Examples\Qt-5.9\charts\legend运行效果:功能详解设置图例标......
  • 关于RestCloud iPaaS平台的板块详解
    当今的企业分工越来越细,上下游合作越来越紧密、各企业之间的业务系统需要相互协作完成业务、外部API依赖越来越多、同时企业系统运行在多个混合云环境及SaaS中,私有端大量业务系统与云端系统形成了错综复杂的集成关系,企业面临集成技术复杂多样、API管理混乱、故障定位困难、数据推......
  • flink之核心抽象--Window窗口及窗口操作全面详解
    flink之核心抽象--Window窗口及窗口操作全面详解标签:flink 窗口 String val -- 元素 Long window1.Windows1.1.基本概念窗口是处理无限流的核心。窗口将流划分为固定大小的“桶”,方便程序员在上面应用各种计算。Window操作是流式数据处理的一种非常核心的抽象,......
  • 视频直播点播平台EasyDarwin基础功能详解
    EasyDarwin是一款基于云计算的视频直播、点播及录像管理解决方案,旨在为用户提供稳定、高效和用户友好的视频流媒体体验。它通过简化视频内容的存储、管理和分享过程,使用户能够轻松构建和管控自己的视频直播和点播系统。在功能方面,EasyDarwin展现出了卓越的核心能力。首先,它的直播......