背景:消息队列为什么出现,解决了什么问题,有什么好处
MQ概念初识
上学时,每节自习课都会有同学零零散散的找老师问问题,一开始就一两人还好,后来渐渐的人多了,老师也有自己的计划工作啥的,不利于时间的管理。于是老师决定让同学们把需要提的问题写在纸上,下自习后交给课代表,然后老师再从课代表那取出要问的问题,然后再一个个解决。
相信在学生时代大家都遇到过上面的这种情况,如果我们将在学校上课抽象成一个系统,那这种情况就是一个很常见的消息队列的使用场景。
在上述实例中,要提的问题就是 消息,提问题的学生是生产者,回答问题的老师是消费者,收集问题的课代表是消息队列。
MQ为什么出现
《道德经》是老子的宇宙生成论,其中“一生二,二生三”广为流传,对于一个软件系统来说,笔者认为这句话也同样适用。所谓一,便是系统的业务需求,无论何人,其编写的每行代码最后都是为了服务业务,或是实现业务功能,或是提升业务性能,最终目的均无法逃离业务。一般意义上,一个公司的业务系统发展脉络基本都是类似的:从单个应用到多个应用,从本地调用到远程调用,随着业务规模的发展,需要对远程服务进行高效的资源管理。于是分布式、集群、微服务等“银弹”便应运而生。
为了分散业务能力,出现了“微服务”;为了分散机器压力,出现了“集群”和“分布式”。那这三者有何关联?我们以一张图来说明:
某大型系统下有众多功能,如订单、视频、物流等。各个功能模块之间虽然在物理层上进行了严格的拆分,但是为了实现业务功能,他们之间的方法调用或者说是函数调用都是非常的频繁且复杂。
如果有 N 个不同系统相互之间都有 RPC(Remote Procedure Call),即远程过程调用,这时候整个系统环境就是一个很大的网状结构,如下图所示,依赖关系有 N*(N-1)/2 个。任何一个系统出问题,都会影响剩下 N-1 个系统,这种强耦合肯定不是我们想要的,那应该怎么降低这种耦合呢?
基于这些问题,消息队列(Message Queue,简称 MQ)技术横空出世,所有的处理请求先作为一个消息发送到 MQ(一般我们叫做 broker),接着处理消息的系统从 MQ 拿到消息并进行处理。这样就实现了各个系统间的解耦,同时可以把失败策略、重试等作为一个机制,对各个应用透明,直接在 MQ 与各调用方的应用接口层面实现即可,如下图所示:
一般来说,我们把发送消息的系统称为消息生产者(message producer),接受处理消息的系统称为消息消费者(message consumer)。
一般来说,我们把发送消息的系统称为消息生产者(message producer),接受处理消息的系统称为消息消费者(message consumer)。
根据消息处理的特点,我们又可以总结两种消息模式:
- 点对点模式(Point to Point,PTP),一个生产者发送的每一个消息,都只能有一个消费者能消费,看起来消息就像从一个点传递到了另外一个点。
- 发布订阅模式(Publish-Subscribe,PubSub),一个生产者发送的每一个消息,都会发送到所有订阅了此队列的消费者,这样对这个消息感兴趣的系统都可以拿到这个消息。
使用 MQ 的好处
从上面的介绍中我们可以看出 MQ 的出现在一定程度上是可以将复杂的服务解耦。
那么回到一开始的例子,我们发现,课代表的出现也确实在一定程度上解决了老师和学生之间的强耦合关系。类似的例子还有快递柜,快递员将快递放到快递柜,不方便拿快递的人可以在下班之后再去拿快递。这样快递员和收快递的人就可以更加自主,只通过一个简单的“容器”——快递柜来联系。你甚至可以不知道你的快递员长什么样子,快递员也可以不知道你是谁,在他们眼里,都只有快递柜,没有对方。
毫无疑问,与一个简单的容器打交道,比与复杂的人打交道容易一万倍,他们也可以更加专注的去完成自己的事情。
那么除解耦外还有其他的优势吗?自然是有的。
再回到一开始学生提问的例子,我们设想另一个场景:如果提问的问题特别难,而且是每个人都要问这个问题,老师给每个人讲解要花很多时间,学生有压力,老师也会觉得麻烦,所以老师决定第二天上课的时候把这个问题单独拿出来说。
在上面这个事例中,就体现了 MQ 的另外两个作用——广播和削峰。
广播:老师只需要讲解一次,所有需要听这道题的同学就都可以听了。
削峰:将当晚那么多同学讲题的需求延迟到第二天上课。
MQ 带来的成本
如此一看,消息队列确实有很多好处,不过凡事皆有利弊,消息队列的使用也是有一定的使用成本的。
1、引入了一定的复杂度
虽然引入了消息队列可以让各个系统解耦,但同时也增加了维护存放消息的容器的成本。
就和例子中的快递柜一样,维护快递柜也是需要成本的,不然前段时间也不会出现丰巢收费的事情了。当过课代表的人也知道自己有多辛苦。
2、暂时的不一致性
同学问问题,老师没办法立即给出解答。快递到了,你不能及时感受拆快递的快感,这些在一个复杂系统中体现出来的就是暂时的不一致性。
不过,就像老话说的,正义可能会迟到,但永远不会缺席。老师最终还是会给你解决问题,你最终还是可以感受到拆快递的快感,这就是所谓的「最终一致性」。
什么情况下适合使用MQ?
1、容忍暂时的不一致性
如果不是对消息的处理非常及时,比如电商系统中的付款和下订单以及物流配送,只要用户最终满意于「尽快收到货」,这种情况就可以使用 MQ。
当然,如果用户对这种情况无法容忍,那就再想想其他办法吧。
2、收益>成本
这点也很好理解,如果使用维护一个消息队列的成本,比消息队列对项目的实际效益要大,那使用他作甚?