上图是之间讨论确定的系统架构(后续内容会按照这个架构来叙述),其中:
-
客户端包含Producer和Consumer两大块
-
客户端需要和NameServer交互来获取元数据
-
客户端需要和Broker交互来读写消息
Client模块划分
1. 网络模块
第一个仍然是网络模块。Client需要获取元数据,需要读写消息,网络模块是必不可少的。 和Broker不同的是,Client的网络模块要简单一些。Broker需要向NameServer汇报数据,同时还要处理来自Client的请求,而Client更多的只是发出请求:
-
向NameServer获取元数据
-
向Broker写入消息
-
从Broker获取消息
2. 编解码模块
Client需要将消息写到Broker,同时也需要从Broker获取消息,这两个过程会涉及到消息的编解码。
3. 元数据相关
Client相关的元数据有Topic、消费进度、Group(之前介绍过的概念,可以看之前的文章),另外还需要感知其他的客户端的存在(叫Member信息或者Client Instance信息吧),所以需要Member数据。那么元数据相关大概是以下组件:
-
TopicManager
-
PositionManager
-
GroupManager
-
MemberManager
4. 发送相关
Producer API
对于Client而言,很重要的一个模块就是暴露出去的发送和消费的API,这是使用方唯一能接触到的地方(写代码时,任何暴露出去的API已经要谨慎谨慎再谨慎)。
对于发送的API,从不同的角度可以分为:
-
从发送方式上有同步发送和异步发送
-
从发送消息量上有单条发送和批量发送
路由模块
对于发送而言,一条消息最终需要落到某一个确定的分区上。所以客户端会包含一个路由模块来根据消息的属性和Topic的元信息来选择分区。
5. 消费相关
Consumer API
消费相关的API会比发送的复杂一些,因为消费需要提供更多的模式。另外为了保证顺序性、减少消息的重复等,消费还需要引入租约等组件。租约和Consumer的各种模式已经是比较细节的问题了,在设计阶段在进行介绍。
分区分配模块
发送方需要选择将消息写入到哪个分区,而消费方需要决定自己消费哪些分区,所以对应于发送方的路由模块,消费方会有分区分配的模块。
缓存模块
为了保证性能,Consumer从Broker获取消息和使用方消费消息是异步的,中间需要Buffer来缓存消息,所以Consumer相对于Producer会多一个缓存模块。
除了以上模块,还会有LifeCycle这样生命周期相关的基础模块,这个也是上一篇在介绍Broker模块时遗漏的。
总结以上内容,Client包含的模块大概如下:
结语
本篇主要是把Client的几个模块划分出来,为之后的详细设计做准备。 下一篇会整理一下NameServer的模块,然后大概会有一到两篇的篇幅总结一些架构、流程、数据流等。
往期内容:
欢迎关注此公众号,将坚持不懈的写MQ相关的技术文章,希望能和更多的朋友交流。