RocketMQ源码阅读 开篇
RocketMQ 是什么?
RocketMQ 是 Alibaba
捐赠给 Apache
的一款分布式、队列模型的开源消息中间件。
从官网也能看出它的一些特性:
- 低延迟
- 高可用
- 万亿级的消息支持
- …
RocketMQ
基本概念
RocketMQ
是由 Producer
、Broker
、Consumer
三部分组成, Producer
负责生产 Message
, Consumer
负责消费 Message
, Broker
负责存储 Message
。
每个 Broker
可以存储多个 Topic
的消息, 每个 Topic
的消息也可以分片存储在不同的 Broker
上。 Message Queue
用于存储消息的物理地址,每个 Topic
的消息地址存储于对歌 Message Queue
中。
Consumer Group
由多个 Consumer
实例组成。
Producer
负责生产消息,同步发送、异步发送、顺序发送、单向发送。同步和异步需要Broker
确认信息,单向发送不需要。Consumer
负责消费消息,一般异步消费。一个消费者会从Broker
拉取消息。(拉取式消费、推动式消费)Broker Server
负责存储、转发消息。 接收Producer
发送来的消息并存储、同时为Consumer
拉取请求做准备。当然也存储这消息相关的元数据(消费组、消费进度偏移、主题、队列消息等)Name Server
为消息路由的提供者。Producer
和Consumer
能够通过 它查找各个Topic
相应的Broker IP 列表
,多个Name Server
组成集群,相互独立、没有信息交换。Message
消息系统所传输信息的物理载体,生产和消费数据的最小单元,每条消息必须属于一个Topic
,RocketMQ
中每个消息拥有一个唯一的MessageID
,且可以携带业务标识的Key
。系统提供通过MessageId
和Key
查询消息的功能Topic
表示一类消息的集合,每个Topic
包含若干条消息,每条消息智只能属于一个topic
,是RocketMQ
进行 消息定义的基本单位。Tag
为消息设置的标志,用于同一个Topic
下区分不同类型的消息。来自同一个业务单元的消息,可以根据不同的业务在同一个主题下设置不同的标签。Tag 能够有效的保持代码清晰度和连贯性,并优化RocketMQ
的查询系统。Consumer
可以根据Tag
实现不同的子主题的不同消费逻辑。Pull Consumer
Push Consumer
Producer Group
Consumer Group
Clustering
Broadcasting
Normal Ordered Message
Strictly Ordered Message
RocketMQ
部署架构
Producer
: 消息发布决赛、支持分布式集群部署,Producer
通过MQ的负载均衡莫款选择相应的Broker
进行消息投递。Consumer
: 消息消费角色、支持分布式集群部署,支持Push方式
、Pull方式
对消息进行消费,同时也指出集群方式
和广播方式
进行消费。Name Server
:NameServer
是一个非常简单的Topic路由注册中心
,其角色类似Dubbo中的zookeeper,支持Broker的动态注册与发现。
Broker管理
,NameServer
接受Broker集群
的注册信息并且保存下来作为路由信息的基本数据。然后提供心跳检测机制,检查Broker
是否还存活;路由信息管理
, 每个NameServer
将保存关于Broker
集群的整个路由信息和用于客户端查询的队列信息。然后Producer
和Consumer
通过NameServer
就可以知道整个Broker集群的路由信息
,从而进行消息的投递和消费。NameServer
通常也是集群的方式部署,各实例间相互不进行信息通讯。Broker
是向每一台NameServer
注册自己的路由信息,所以每一个NameServer
实例上面都保存一份完整的路由信息。当某个NameServer
因某种原因下线了,Broker
仍然可以向其它NameServer
同步其路由信息,Producer
,Consumer
仍然可以动态感知Broker
的路由的信息
RocketMQ
网路部署特点:
NameSever
是无状态节点,可集群部署,节点之间无任何信息同步。Broker
是向每一台NameServer
注册自己的路由信息,所以每一个NameServer
实例上面都保存一份完整的路由信息。当某个NameServer
因某种原因下线了,Broker
仍然可以向其它NameServer
同步其路由信息,Producer
,Consumer
仍然可以动态感知Broker
的路由的信息。Broker
部署相对复杂,Broker
分为Master
与Slave
,一个Master
可以对应多个Slave
,但是一个Slave
只能对应一个Master
,Master
与Slave
的对应关系通过指定相同的BrokerName
,不同的BrokerId
来定义,BrokerId为0
表示Master
,非0
表示Slave
。Master
也可以部署多个。每个Broker
与NameServer
集群中的所有节点建立长连接,定时注册Topic
信息到所有NameServer
。 注意:当前RocketMQ
版本在部署架构上支持一Master多Slave
,但只有BrokerId=1
的从服务器才会参与消息的读负载。Producer
与NameServer
集群中的其中一个节点(随机选择)建立长连接,定期从NameServer
获取Topic路由信息
,并向提供Topic
服务的Master
建立长连接,且定时向Master
发送心跳。Producer
完全无状态,可集群部署。Consumer
与NameServer
集群中的其中一个节点(随机选择)建立长连接,定期从NameServe
r获取Topic路由信息
,并向提供Topic
服务的Master
、Slave
建立长连接,且定时向Master
、Slave
发送心跳。Consumer
既可以从Master
订阅消息,也可以从Slave
订阅消息,消费者在向Master
拉取消息时,Master
服务器会根据拉取偏移量与最大偏移量的距离(判断是否读老消息,产生读I/O
),以及从服务器是否可读等因素建议下一次是从Master
还是Slave
拉取。
RocketMQ
* 事务消息 *
后面专门一章讲述这个事务消息