我们不会平白无故引入一个技术栈,一定是看重它的某些特性,毕竟引入一个技术可能存在弊端和风险。我们在谈论为什么使用消息队列的时候一定要根据具体业务来,比如在实际业务中遇到了什么困难,如果不使用消息队列就很棘手,通过使用消息后解决了哪些问题。这里总结了三点比较核心原因:解耦、异步、削峰。
解耦
在某个场景下,A系统需要向BCD系统通过接口调用发送一条数据过去,这个时候E系统也要数据,D系统也要数据,此时A系统内心肯定是崩溃的。
上诉场景中A系统和其他系统耦合性很高,每当产生一条数据的时候A系统都要考虑到其他系统是否在线?是否挂掉?是否接收正常?所以A系统真的是太难了!
如果使用MQ,A系统产生一条数据后就放进MQ,其他系统需要就自己到MQ系统中去消费,不需要就可以取消对该消息的订阅,A系统压根不需要再考虑给其他系统发送数据的各种乱七八糟问题。
总结:通过一个MQ,Pub/Sub发布订阅消息这么一个模型,A系统就跟其它系统彻底解耦了。
异步
在某场景下,A系统收到一条数据后需要在自己本地写库,同时还要在BCD三个系统写库,自己本地写库要3ms,BCD三个系统分别写库要300ms、450ms、200ms。总共要延时3+300+450+200=953ms,接近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系统就会快速将积压的消息给解决掉。
上面吹了消息队列的一堆优点,但是也不能不知道使用它带来的一些缺点吧!缺点有以下几点:
系统引入的外部依赖越多,越容易挂掉。本来你就是A系统调用BCD三个系统的接口就好了,人ABCD四个系统好好的,没啥问题,你偏加个MQ进来,万一MQ挂了咋整,MQ一挂,整套系统崩溃的,你不就完了?
硬生生加个MQ进来,你怎么保证消息没有重复消费?怎么处理消息丢失情况?怎么保证消息传递的顺序性?头大头大,问题一大堆,痛苦不已。
A系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是BCD三个系统那里,BD两个系统写库成功了,结果C系统写库失败了,咋整?你这数据就不一致了。
所以消息队列实际是一种非常复杂的架构,你引入它有很多好处,但是也得针对它带来的坏处做各种额外的技术方案和架构来规避掉,做好之后,你会发现,妈呀,系统复杂度提升了一个数量级,也许是复杂了10倍。但是关键时刻,用,还是得用的。
以上就是极悦小编介绍的"消息队列MQ详解",希望对大家有帮助,想了解更多可查看Java教程。极悦在线学习教程,针对没有任何Java基础的读者学习,让你从入门到精通,主要介绍了一些Java基础的核心知识,让同学们更好更方便的学习和了解Java编程,感兴趣的同学可以关注一下。
你适合学Java吗?4大专业测评方法
代码逻辑 吸收能力 技术学习能力 综合素质
先测评确定适合在学习