为什么要使用MQ?

我们已经知道MQ 是什么了,那在什么地方可以用MQ,或者说,为什么要使用MQ 呢?这是一个很常见的面试题,如果你在项目里面用了MQ,还不知道这个问题的答案,说明你自己从来没有思考总结过,因为这个项目是别人架构设计的,你可能只是做了些维护的工作。有一天让你自己去做项目架构的时候,你搞一个MQ 进去,理由就是以前的项目也是这么干的,这是很危险的。

实现异步通信

同步的通信是什么样的?

发出一个调用请求之后,在没有得到结果之前,就不返回。由调用者主动等待这个调用的结果。

而异步是相反的,调用在发出之后,这个调用就直接返回了,所以没有返回结果。也就是说,当一个异步过程调用发出后,调用者不会马上得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。

为什么要使用MQ?_第1张图片

为什么要使用MQ?_第2张图片

举个例子:

大家都用过手机银行的跨行转账功能。大家用APP 的转账功能的时候,有一个实时模式,有一个非实时模式。

实时转账实际上是异步通信,因为这个里面涉及的机构比较多,调用链路比较长,本行做了一些列的处理之后,转发给银联或者人民银行的支付系统,再转发给接收行,接受行处理以后再原路返回。

所以转账以后会有一行小字提示:具体到账时间以对方行处理为准,也就是说转出行只保证了这个转账的消息发出。那为什么到账时间又这么快呢?很多时候我们转账之后,不用几秒钟对方就收到了。是因为大部分的MQ 都有一个低延迟的特性,能在短时间内处理非常多的消息。

很多理财软件提现也是一样,先提交请求,到账时间不定。这个是用MQ 实现系统间异步通信的一个场景。

实现系统解耦

第二个主要的功能,是用来实现系统解耦。既然说到解耦,那我们要先来了解一下耦合的概念。

耦合是系统内部或者系统之间存在相互作用,相互影响和相互依赖。

在我们的分布式系统中,一个业务流程涉及多个系统的时候,他们之间就会形成一个依赖关系。

比如我们以12306 网站退票为例,在传统的通信方式中,订单系统发生了退货的动作,那么要依次调用所有下游系统的API,比如调用库存系统的API 恢复库存,因为这张火车票还要释放出去给其他乘客购买;调用支付系统的API,不论是支付宝微信还是银行卡,要把手续费扣掉以后,原路退回给消费者;调用通知系统API 通知用户退货成功。

这个过程是串行执行的,如果在恢复库存的时候发生了异常,那么后面的代码都不会执行。由于这一系列的动作,恢复库存,资金退还,发送通知,本质上没有一个严格的先后顺序,也没有直接的依赖关系,也就是说,只要用户提交了退货的请求,后面的这些动作都是要完成的。库存有没有恢复成功,不影响资金的退还和发送通知。

如果把串行改成并行,我们有什么

(多线程)

多线程或者线程池是可以实现的,但是每一个需要并行执行的地方都引入线程,又会带来线程或者线程池的管理问题。

所以,这种情况下,我们可以引入MQ 实现系统之间依赖关系的解耦合。

引入MQ 以后:

订单系统只需要把退货的消息发送到消息队列上,由各个下游的业务系统自己创建队列,然后监听队列消费消息。

在这种情况下订单系统里面就不需要配置其他系统的IP、端口、接口地址了,因为它不需要关心消费者在网络上的什么位置,所以下游系统改IP 没有任何影响。甚至不需要关心消费者有没有消费成功,它只需要把消费发到消息队列的服务器上就可以了。

这样,我们就实现了系统之间依赖关系的解耦。

实现流量削峰

第三个主要功能,是实现流量削峰。

在很多的电商系统里面,有一个瞬间流量达到峰值的情况,比如京东的618,淘宝的双11,还有小米抢购。普通的硬件服务器肯定支撑不了这种百万或者千万级别的并发量,就像2012 年的小米一样,动不动服务器就崩溃。

如果通过堆硬件的方式去解决,那么在流量峰值过去以后就会出现巨大的资源浪费。那要怎么办呢?如果说要保护我们的应用服务器和数据库,限流也是可以的,但是这样又会导致订单的丢失,没有达到我们的目的。

为了解决这个问题,我们就可以引入MQ,MQ 既然是队列,一定有队列的特性,我们知道队列的特性是什么?

(先进先出FIFO)

这样,我们就可以先把所有的流量承接下来,转换成MQ 消息发送到消息队列服务器上,业务层就可以根据自己的消费速率去处理这些消息,处理之后再返回结果。就像我们在火车站排队一样,大家只能一个一个买票,不会因为人多就导致售票员忙不过来。如果要处理快一点,大不了多开几个窗口(增加几个消费者)。

这个是我们利用MQ 实现流量削峰的一个案例。

如果大家的公司里面有用到MQ 的话,也可以对号入座看看是起到了什么作用。

总结起来:

1) 对于数据量大或者处理耗时长的操作,我们可以引入MQ 实现异步通信,减少客户端的等待,提升响应速度。

2) 对于改动影响大的系统之间,可以引入MQ 实现解耦,减少系统之间的直接依赖。

3) 对于会出现瞬间的流量峰值的系统,我们可以引入MQ 实现流量削峰,达到保护应用和数据库的目的。

所以对于一些特定的业务场景,MQ 对于优化我们的系统还是有很大的帮助的,那么大家想一下,把传统的RPC 通信改成MQ 通信会不会带来一些问题呢?

使用消息队列带来的一些问题

系统可用性降低:原来是两个节点的通信,现在还需要独立运行一个服务,如果MQ服务器或者通信网络出现问题,就会导致请求失败。

系统复杂性提高: 为什么说复杂?第一个就是你必须要理解相关的模型和概念,才能正确地配置和使用MQ。第二个,使用MQ 发送消息必须要考虑消息丢失和消息重复消费的问题。一旦消息没有被正确地消费,就会带来数据一致性的问题。

所以,我们在做系统架构的时候一定要根据实际情况来分析,不要因为我们说了这么多的MQ 能解决的问题,就盲目地引入MQ。

 

你可能感兴趣的:(为什么要使用MQ?)