消息中间件实践-现代消息中间件基本构成

2019/01/12 中间件技术

从本地队列到消息中间件

通过介绍本地基于IPC共享内存方式实现的消息队列思路之后,我们再来看看一个消息中间件都包括哪些组成部分,这些组成部分在原先本地队列上是否都存在这样的需求,基于本地队列模型是怎么一步步到消息中间件演进上来的。(进而如果让我们自己来开发一个消息中间件,大概是怎么一步步的实现的。)

消息队列原先作为本地进程之间通信手段,承担着本地进程之间数据快速流动的能力。帮助进程之间以一种数据流的方式进行通信协作完成业务任务处理。随着应用软件的分布式化,软件领域的交互协作从过去多进程间本地共享手段,尽可能少的网络通信模式在向更多网络分布式通信手段,较少的本地共享通信模型转变。因为网络通信的能力加入,让原本本地软件能力交互协作更加的灵活,支持软件在计算资源和处理能力上的横向扩展,更加弹性。

Alt text
消息队列到中间件化的过程,就是队列模型的网络能力化的过程。本地消息队列更多的关注本地存储模型以及对外提供的使用库的API能力,具备分布式能力的消息中间件则需要关注提供的消息队列存储模型能力是通过网络通信的组件实现的。

消息中间件基本结构

在不考虑高可用的情况下,一个典型的消息中间件组成结构如下:
Alt text
消息中间件以C/S结构方式面向应用提供能力,虽然也支持客户端采用服务化方式访问,但是考虑到性能等方面,当前主流模式还是以支持SDK的方式为主。
1)核心消息队列存储模型
这个核心的队列存储模型,目前开源业界的不同开源消息中间件如,kafka、rocketmq、activemq等实现思路不同。
后续会选取个rocketmq开源的消息中间件存储模型剖析一下,其他的开源消息中间件大多存储模型相差不大,
消息中间件的存储模型是核心功能,更多的功能特性也都基于该存储模型基础上实现。下一篇会选取rocketmq的核心存储模型分析一下,对消息队列的broker有个基本认识。
2)面向应用提供的生产者、消费者服务的能力
目前各类消息中间件都封装了网络通信能力的SDK提供外部应用使用,SDK中包括了消息中间件开放出来特性的API。

理解一种技术的框架、或者中间件,最佳的方式建议是从开放给应用的功能角度入手,进而窥探到 框架或者中间件的全貌。对于消息中间件,开放给应用的API接口以及相关的特性是深入理解消息中间件的突破口。
相较于本地消息队列实现,同样的消息的“读、写”两个重要接口能力是消息中间件最核心的入口功能。在本地消息队列时期,为了区分业务的消息在消息队列的不同通道存放实现,通常会给封装的队列打上业务属性标记。

1)topic:
这个站在业务角度的属性标记在消息中间件中抽象为topic。

Alt text
也就是应用与一个中间件之间有一个topic定义的属性来区分你将会将消息发往哪个队列,消费者应用根据topic从哪个队列消费消息数据。

2)queue:
如果消息存储模型上支持按照topic划分逻辑队列的能力,那么根据不同的topic可能会定义1….n个queue,这个queue在不同的开源消息中间件中有的称为Partition,有的称之为queue。在本地消息队列中,我们可以回忆起,其实就是类似cache块的定义,在内存中封装的一块连续队列的模型。

Alt text
不管是queue还是Partition,本质上是为了站在业务角度,让存放的消息数据在生产和消费的时候站在业务等多个维度都具有一定的逻辑或者物理的隔离性。
Topic是面向业务定义的主题,那么queue是在存储模型上的隔离性考虑的逻辑划分或者物理划分。(这里逻辑或者物理是因为不同的开源消息中间件在这方面的实现不同,有的将每个queue物理化隔离,有的是通过统一的存储文件在内部通过逻辑隔离方式来实现多queue化)。

3)消息读写功能:
对于消息队列的写入方,称为producer。对于消息的读取消费方,称为consumer。

Alt text
消息的读写API通常在中间件的客户端包中封装提供,通过RPC通信方式和中间件的核心存储模型服务交互。
消息的写API在生产者中,消息的读API在消费者中;另外,消息的业务请求和消费与具体的中间件提供的读写接口之间也存在多线程模型,支持多线程生产或消费。

总结:
在不考虑高可用的情况下,单个消息中间件核心组成部分如下:
1)核心存储模型
2)生产和消费者客户端(支持消息读写)
3)生产和消费客户端与存储模型服务之间RPC
下一步通过分析主流开源的消息中间件,对消息中间件深入认识的基础上,再去考虑封装实现自研的消息中间件雏形。

Search

    Table of Contents