消息中间件(1)

问题的起源

​ 在深入了解消息中间件之前,我想先搞清楚为什么会出现消息中间件这么一款产品,换句话说我们需要弄清楚消息中间件到底解决了一个什么问题。

​ 在互联网的初级阶段,那个时候一方面没有想现在如此多的用户,另一方面也没有太复杂的业务场景,在那个阶段,应用的架构往往是垂直式的,通俗的讲就是在一个工程中解决所有的问题。那么从进程角度来看,在这一阶段中所有的问题都在一个进程中解决。在这样的大背景下,一个应用同样会分层、会分模块,但是这样的划分往往是逻辑上的,从进程角度而言,模块之间的数据交互是通过进程内的函数调用,或者一些公共类来完成,这个阶段的数据交互没有太多复杂的要求也没有太多复杂操作。

​ 随着业务的发展,用户数量越来越多,同时应用的业务场景也越来越复杂,应用的功能也越来越丰富,此时为了满足业务发展需求同时提高开发效率,应用的各个模块开始拆分,每个模块开始独立开发、独立测试、独立发布、独立的下线。此时由于应用的复杂性可控,模块之间的数据交互可能是用一些restful的接口,也有可能使用的RPC方式,在这种方式下,模块之间的调用逻辑清晰,问题排查方便迅速,从进程角度看,模块之间的数据交互是不同进程之间的数据交互,而这些进程往往是不同节点上的进程,通过网络交换数据。

​ 随着业务的进一步发展,越来越多的业务场景被挖掘出来,同时该应用的功能进一步的丰富,而传统的模块之间使用RPC进行数据交互的方式越来越制约业务的发展,例如,新增一个业务模块,会造成大量的模块进行改造,增加RPC调用接口,同时某一个模块下线也需要大动干戈的对其他模块进行改造,在这种大背景下,模块之间通过RPC进行数据交互的复杂度完全失控,模块的上线,下线都将会涉及到大规模的其他模块的改造。

​ 在计算机的世界中,没有什么问题不是一个中间层不能解决的,如果有,那就再加一层。依据这个思路,模块之间的数据交互可以通过增加一个第三方的中间层来解决,这个第三方就是消息中间件。

消息中间件的职责

​ 上一节我们分析了为什么会出现消息中间件,那么对于消息中间件的职责这个问题的答案就呼之欲出。对于一款消息中间件而言,它最基本的功能就是负责模块之间的消息交互。但是这个最基本的功能却不像它看起来那么简单。

​ 在目前的微服务结构中,某些模块之间的数据交互由消息中间件来承担,从消息中间件的角度而言,它负责从消息的生产方拿到消息,再将消息投递到消息的消费放,在这个环节中消息的生命周期如下,1、消息被生产者生产,2、消息被生产者投递,3、消息在消息队列中存储,4、消息被消息队列交付,5、消息被消费者消费。在消息的生命周期中2、3、4都和消息队列相关,因此消息中间件一般需要如下的几个功能。

​ 1、高可用。消息中间件应当尽量避免发生宕机问题,否则会影响到整个系统的可用性。消息中间件宕机,则生产者和消费者完全失去了数据交互的途径。

​ 2、具备稳定的交付投递能力,消息在从生产者投递到消息中间件的过程中消息的状态不应该出现二义性,要么已经投递,要么投递失败,同理消息在从消息中间件交付到消费者的过程中也不应当存在二义性。

​ 3、具备一定的消息积压能力,一般而言生产者的处理能力和消费者的处理能力不一定匹配,在这个过程中很可能会出现消息大量的堆积在消息中间件的队列中,消息中间件需要具备消息堆积能力,并且在这个场景下仍要保证消息中间件的性能。

​ 4、消息的固化能力,消息中间件的本职工作是架起生产者和消费者的桥梁,因此在理论上消息中间件不应当出现丢消息的现象,就算在某些不得已的场景下需要丢弃部分消息,也需要某些类似重传的机制。

消息中间件的一般结构

​ 在消息中间件的的模型中一般存在一下几个基本角色:

​ 1、生产者。生产者负责产生消息并将消息投递到消息队列

​ 2、消息的存储管理队列。消息在被投递后,一般在此处暂存,等待交付

​ 3、消息的消费者。消费者负责消费消息,

​ 一般而言除了以上三种最基本的角色外,为了完善消息队列的功能,还会存在下列角色

​ 消息队列的协调者,该角色负责协调消息的存储队列,一般而言,生产者和消费者从协调者处得到消息存储队列的相关信息,从而和消息存储队列进行交互。该角色还监控检查消息存储队列的状态。

原文地址:https://www.cnblogs.com/establish/p/14136018.html