转载自https://blog.csdn.net/hao2244/article/details/109210541
系列文章目录:https://blog.csdn.net/hao2244/article/details/109240455
概述
RocketMQ是一款较为流行的消息中间件。和Kafka类似,其也采用"发布-订阅"业务模型。即将消息按"主题"(Topic)组织起来,生产者向指定Topic中投递消息,消费者可选择订阅一些Topic以获取消息。RocketMQ由阿里研发,后入选Apache基金会顶级项目。由于其低延时、高吞吐的表现,在众多公司内得到了广泛的应用。本文从宏观角度对其基本架构作一个简要介绍。
基本架构
首先给张图:
RocketMQ架构上涉及4中角色:Producer、Broker、Consumer、NameServer。接下来一一细说。
Producer
Producer是消息生产者,负责将消息发送到对应的Broker。除了这个基本功能外,RocketMQ还赋予Producer事务控制的能力,使得本地事务和Broker消息存储形成一个分布式事务。这部分内容后面会有文章详细介绍。
Broker
Broker负责消息存储。在描述Broker架构之前先来考虑两个问题:
- 消息中间件涉及的数据量可不小,大规模数据如何存储?
- 如何提升架构可用性,即使挂掉几个节点也不影响服务?
Broker的组织方式就是围绕这两个问题来的。
针对第一个问题,业内通用的一般解决方案就是"分片"。即将海量数据通过特定规则划分成很多子集,这样就可以拉来很多太机器,每台机器只存储少数几个子集,最终获得横向扩展的能力。在RocketMQ中,这种"子集"就是MessageQueue。Topic内的数据被划分成多个MessageQueue,各Broker节点以MessageQueue为最小单位领取自己的"存储任务"。
第二个问题,一般方案就是"复制"(或称"备份"、"副本"),即同一份数据复制多份并保存在不同节点上,这样只要不是全部节点都挂掉,系统就还可以正常提供数据。RocketMQ的Broker分为"主"、"从"两种角色,同时通过"推拉混合"的方式将主节点的数据同步至从节点(后面会有文章详细介绍)。理论上,从节点就是主节点的数据拷贝,主节点挂掉后从节点可以顶替。
Consumer
Consumer负责从Broker处拉取消息,执行消费逻辑。在RocketMQ官方提供的客户端中,Consumer提供了push和pull两种消费模式(其通信层面的实现都是pull),同时对顺序消费等常见问题也有所支持。
NameServer
上文提到过,一个Topic下的多个MessageQueue可能会分布在多台机器。那么无论是"Producer向目标MessageQueue投递消息"还是"Consumer拉取目标MessageQueue内的数据"都面临一个共同问题:如何确定改MessageQueue当前在哪台机器上?答案就是NameServer。
NameServer负责保存"集群元数据",包括Broker列表、Topic列表、MessageQueue列表、MessageQueue和Broker间的承载关系等数据。Producer和Consumer在与Broker通信之前要查询NameServer,以确定投递消息或拉取消息的目标Broker到底是哪个。
NameServer属无状态服务,可轻松进行横向扩展以保证可用性。
源码结构
注释版源码:https://github.com/Hao1296/rocketmq
源码重要目录如下:
- broker:Broker源码
- client:客户端源码(包括Producer和Consumer)
- common:基础数据结构
- filter:消息过滤相关代码
- namesrv:NameServer代码
- store:消息存储代码