为什么使用消息队列


解耦

看这样的业务场景,A系统发送数据到B、C、D三个系统,通过接口调用发送。如果E系统也要这个数据呢?那如果C系统现在不需要了呢?A系统负责人几乎崩溃......

在这个业务场景中,A系统跟其它各种乱七八糟的系统严重耦合,A系统产生一条比较关键的数据,很多系统都需要A系统将这个数据发送过来。A系统要时刻考虑B、C、D、E四个系统如果挂了该咋办?要不要重发,要不要把消息存起来?

如果使用MQ,A系统产生一条数据,发送到MQ中去,哪个系统需要数据就自己去MQ里面消费。如果新系统需要数据,直接从MQ里消费即可;如果某个系统不需要这条数据了,就取消对MQ消息的消费即可。这样的话A系统压根儿不需要去考虑要给哪个系统发送数据,不需要维护这个代码,也不需要考虑其他系统是否调用成功、失败超时等情况。

异步

再来看这样一个业务场景,A系统接收一个请求,需要在自己本地写库,还需要在B、C、D三个系统写库,自己本地写库要3ms,B、C、D三个系统分别写库要300ms、450ms、200ms。最终请求总延时是3+300+450+200=953ms,接近1s,用户感觉搞个什么东西,慢死了慢死了。用户通过浏览器发起请求,等待个1s,这几乎是不可接受的。

一般互联网类的企业,对于用户直接的操作,一般要求是每个请求都必须在200ms以内完成,对用户几乎是无感知的。采用MQ,那么A系统连续发送3条消息到MQ队列中,假如耗时5ms,A系统从接受一个请求到返回响应给用户,总时长是3+5=8ms,对于用户而言,其实感觉上就是点个按钮,8ms以后就直接返回了。

削峰

每天0:00到12:00,A系统风平浪静,每秒并发请求数量就50个。结果每次一到12:00到13:00,每秒并发请求数量突然会暴增到5k+条。但是系统是直接基于MySQL的,大量的请求涌入MySQL,每秒钟对MySQL执行约5k条SQL。

一般的MySQL,扛到每秒2k个请求就差不多了,如果每秒请求到5k的话,可能就直接把MySQL给打死了,导致系统崩溃,用户也就没法再使用系统了。但是高峰期一过,到了下午的时候,就成了低峰期,可能也就1w的用户同时在网站上操作,每秒中的请求数量可能也就50个请求,对整个系统几乎没有任何的压力。

如果使用MQ,每秒5k个请求写入MQ,A系统每秒钟最多处理2k个请求,因为MySQL每秒钟最多处理2k个。A系统从MQ中慢慢拉取请求,每秒钟就拉取2k个请求,不要超过自己每秒能处理的最大请求数量就OK,这样下来,哪怕是高峰期的时候,A系统也绝对不会挂掉。而MQ每秒钟5k个请求进来,就2k个请求出去,结果就导致在中午高峰期(1个小时),可能有几十万甚至几百万的请求积压在MQ中。

这个短暂的高峰期积压是OK的,因为高峰期过了之后,每秒钟就50个请求进MQ,但是A系统依然会

按照每秒2k个请求的速度在处理。所以说只要高峰期一过,A系统就会快速将积压的消息给解决掉。

elk