什么是Queue?
要知道什么是消息队列,首先就要知道什么是队列。相信只要你只要学习过数据结构就肯定不会对它感到陌生,它是一种符合先进先出(FIFO)规则的线性表
队列只允许在其末尾进行插入,在其头部进行删除,这和我们在排队的时候的场景十分类似,在Java中队列是通过链表来实现的,其底层基于LinkedList实现了Queue接口。
什么是Message Queue?
知道了队列,再来看看消息队列,它是作为一个单独的中间件存在的,如下图,Service 0想调用任何一个服务的接口来使用,都要经过消息队列来进行中转,经由消息队列告诉各个服务你要干什么,而Service 0只需要发布个事件就行了
试想一下,如果没有MQ的存在,如果这个时候Service 0需要调用的服务有变化了,我就得去改它的代码调新的接口,如果有异常还得做更多操作,这就导致各个服务之间存在强耦合,这显然不符合我们微服务架构的思想。
而如今有了消息队列,Service 0就不需要关心后续的问题,只用向MQ发布一个事件,再由MQ转告其它的服务进行处理就完了,整个系统的耦合度也因此大大降低。
而这就是消息队列的优势之一:应用解耦
再来看下面这张图,在没用到消息队列的时候,我们的各服务是同步运行的,这也就意味着,用户想要知道执行完这个操作就要等所有的服务一个个处理完才行,等这它们同步处理完把这时间加起来要过去好久,用户等的花儿都谢了早就跑了。
而我们加入了消息队列后,我们直接与用户打交道的Service 0只需要发布一个事件交付给MQ,交付完了直接反馈给用户就行了,而用户关心的操作反馈收到了,后续的操作也由消息队列通知后进行处理了,这不就两全其美。
这一般适用于后续操作比较耗时但无需实时返回处理结果的操作场景,就比如用户在电商平台进行支付,他只关心自己支付成功没有,后面订单如何处理对他而言是不需要去关心的,引入了消息队列实现异步化之后就很好地解决了这个问题了。
这就是消息队列的第二个优势:异步处理
而它还有一个一个优势就是:流量削峰
我们都知道大型电商平台都有双十一,那这种时候用户流量特别大,可能我一秒钟就得处理几千份订单,那我这么多用户同时访问服务器,数量一多肯定是撑不住的,这个时候如果我们的消息队列在中间充当一个枢纽的作用,后续的服务集群太多了处理不过来怎么办?那就排成队列,一个个处理不就行了。
这样一来短时间内高并发就被匀到了更长时间去处理,避免了短时高流量导致的服务崩溃,这也就是所谓的流量削峰。
消息队列之劣处
显然的由于我们把大量的消息放在MQ中,这就导致整个系统中消息队列的高可用变得极为关键,这么多服务与消息队列关系紧密,一旦它挂了那各个服务就都会出问题。
其次,经由MQ中转消息的系统与单体项目中至关的调接口不同,这也导致需要考虑万一这执行流程中出了什么错,就很难追踪到这个问题是出在哪的,系统也因此变得更加复杂了。