MQ是什么?

95 阅读5分钟

MQ

  • 概念
    是基础数据结构中“先进先出的一种数据结构”,一般用来解决应用解耦,异步消息,流量削峰等问题,实现高性能,高可用,可伸缩和最终一致性框架。把要传输的数据(消息)放在队列中,用队列机制来实现消息传递--生产者生产消息并把消息放入队列,然后由消费者去处理。消费者可以到指定队列拉取消息,或者订阅相应的队列,由MQ服务端给其推送消息。
  • 作用
    主要解决:应用解耦,异步消息,流量削峰等问题,实现高性能,高可用,可伸缩和最终一致性框架。
    解耦:一个业务需要多个模块共同实现,或者一条消息有多个系统需要对应处理,只需要主业务完成以后,发送一条MQ,其余模块消费MQ消息,即可实现业务,降低模块之间的耦合。
    异步:主业务之行结束后从属业务通过MQ,异步执行,降低业务的响应时间,提高用户体验。
    削峰:高并发情况下,业务异步处理,提供高峰期业务处理能力,避免系统瘫痪。\
  • 缺点
    ①系统可用性降低:系统引入的外部依赖越多,系统要面对的风险越高,拿场景一来说,本来ABCD四个系统配合的好好的,没啥问题,但是你偏要弄个MQ进来插一脚,虽然好处挺多,但是万一MQ挂掉了呢,那样你系统不也就挂掉了。
    ②系统复杂程度提高:非要加个MQ进来,如何保证没有重复消费呢?如何处理消息丢失的情况?怎么保证消息传递的顺序?问题太多。
    ③一致性的问题:A系统处理完再传递给MQ就直接返回成功了,用户以为你这个请求成功了,但是,如果在BCD的系统里,BC两个系统写库成功,D系统写库失败了怎么办,这样就导致数据不一致了。
    所以。消息队列其实是一套非常复杂的架构,你在享受MQ带来的好处的同时,也要做各种技术方案把MQ带来的一系列的问题解决掉,等一切都做好之后,系统的复杂程度硬生生提高了一个等级。
  • 解耦
    • 该场景中,BCDE都需要用到A系统提供的数据,A系统跟其他四个系统严重耦合,需要时时刻刻考虑其他四个系统要是挂了怎么办,需不需要重新发送数据给他们,这个时候的A系统内心是崩溃的。
    • 但是如果使用了MQ之后 ,A系统的数据只需要放到MQ里面,其他的系统想请求获取数据只需要去MQ里面消费即可,如果突然不想请求了,就取消对MQ的消费就行了,A系统根本不需要考虑给谁去响应这个数据,也不需要去维护代码,也不用考虑其他系统是否调用成功,失败超时等情况。
  • 异步调用
    • 还是ABCD四个系统,A系统收到一个请求,需要在自己本地写库,还需要往BCD三个系统写库,A系统自己写本地库需要3ms,往其他系统写库相对较慢,B系统200ms ,C系统350ms,D系统400ms,这样算起来,整个功能从请求到响应的时间为3ms+200ms+350ms+400ms=953ms,接近一秒,对于用户来说,点个按钮要等这么长时间,基本是无法接受的。
    • 如果用了MQ,用户发送请求到A系统耗时3ms,A系统发送三条消息到MQ,假如耗时5ms,用户从发送请求到相应3ms+5ms=8ms,仅用了8ms,用户的体验非常好。
  • 流量削峰
    • 假设JD数据库没秒能处理1.5w条并发请求(并非实际数据,主要为了举例),到八点抢购的时候,每秒并发百万,这直接导致系统异常,但是八点一过,可能也就几万用户在线操作,每秒的请求可能也就几百条,对整个系统毫无压力。
    • 如果使用了MQ,每秒百万个请求写入MQ,因为JD系统每秒能处理1W+的请求,JD系统处理完然后再去MQ里面,再拉取1W+的请求处理,每次不要超过自己能处理的最大请求量就ok,这样下来,等到八点高峰期的时候,系统也不会挂掉,但是近一个小时内,系统处理请求的速度是肯定赶不上用户的并发请求的,所以都会积压在MQ中,甚至可能积压千万条,但是高峰期过后,每秒只会有一千多的并发请求进入MQ,但是JD系统还是会以每秒1W+的速度处理请求,所以高峰期一过,JD系统会很快消化掉积压在MQ的请求,在用户那边可能也就是等的时间长一点,但是绝对不会让系统挂掉。
  • 四大主流mq