整理了一些RocketMQ相关流程图/原理图,作一下笔记,你们一块儿学习。html
RocketMQ是开源的消息中间件,它主要由NameServer,Producer,Broker,Consumer四部分构成。 java
NameServer主要负责Topic和路由信息的管理,功能相似Dubbo的zookeeper。数组
消息生产者,负责产生消息,通常由业务系统负责产生消息。缓存
消息中转角色,负责存储消息,转发消息。服务器
消息消费者,负责消息消费,通常是后台系统负责异步消费。数据结构
NameServer是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。架构
Broker分为Master与Slave,一个Master能够对应多个Slave,可是一个Slave只能对应一个Master,Master与Slave的对应关系经过指定相同的BrokerName,不一样的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master也能够部署多个。每一个Broker与Name Server集群中的全部节点创建长链接,定时注册Topic信息到全部Name Server。app
Producer与Name Server集群中的其中一个节点(随机选择)创建长链接,按期从Name Server取Topic路由信息,并向提供Topic服务的Master创建长链接,且定时向Master发送心跳。Producer彻底无状态,可集群部署。运维
Consumer与Name Server集群中的其中一个节点(随机选择)创建长链接,按期从Name Server取Topic路由信息,并向提供Topic服务的Master、Slave创建长链接,且定时向Master、Slave发送心跳。Consumer既能够从Master订阅消息,也能够从Slave订阅消息,订阅规则由Broker配置决定。异步
用来表示一个发送消息应用,一个 Producer Group 下包含多个 Producer 实例,能够是多台机器,也能够 是一台机器的多个进程,或者一个进程的多个 Producer 对象。一个 Producer Group 能够发送多个 Topic 消息,Producer Group 做用以下:
用来表示一个消费消息应用,一个 Consumer Group 下包含多个 Consumer 实例,能够是多台机器,也可 以是多个进程,或者是一个进程的多个 Consumer 对象。一个 Consumer Group 下的多个 Consumer 以均摊 方式消费消息,若是设置为广播方式,那么这个 Consumer Group 下的每一个实例都消费全量数据。
Tag表示消息的第二级类型,好比交易消息又能够分为:交易建立消息,交易完成消息等。RocketMQ提供2级消息分类,方便灵活控制。
组,一个组能够订阅多个Topic。
消息的物理管理单位。一个Topic下能够有多个Queue,Queue的引入使得消息的存储能够分布式集群化,具备了水平扩展能力。
在 RocketMQ 中,全部消息队列都是持久化,长度无限的数据结构,所谓长度无限是指队列中的每一个存储单元都是定长,访问其中的存储单元使用 Offset 来访问,offset 为 java long 类型,64 位,理论上在 100年内不会溢出,因此认为是长度无限。
也能够认为 Message Queue 是一个长度无限的数组,Offset 就是下标。
消费消息的顺序要同发送消息的顺序一致,在 RocketMQ 中,主要的是局部顺序,即一类消息为知足顺 序性,必须 Producer 单线程顺序发送,且发送到同一个队列,这样 Consumer 就能够按照 Producer 收送 的顺序去消费消息。
消息存储文件,全部消息主题的消息都存储在 CommitLog 文件中。 Commitlog 文件存储的逻辑视图如图所示
消息消费队列,消息到达 CommitLog 文件后,将异步转发到消息 消费队列,供消息消费者消费。ConsumeQueue存储格式以下:
消息索引文件,主要存储消息 Key 与 Offset 的对应关系。
消息消费队列是RocketMQ专门为消息订阅构建的索引文件,提升根据主题与消息队 列检索消息的速度 ,另外 RocketMQ 引入了 Hash 索引机制为消息创建索引, HashMap 的设 计包含两个基本点 : Hash 槽与 Hash 冲突的链表结构。 RocketMQ 索引文件布局如图所示
lndexFile 总共包含 lndexHeader、 Hash 槽、 Hash 条目
存储每条消息的事务状态。
每个延迟级别对应一个消息消费队列,存储延迟队列的消息拉取进度。
Broker端对消息进行读取和写入的业务逻辑入口,这一层主要包含了业务逻辑相关处理操做(根据解析RemotingCommand中的RequestCode来区分具体的业务操做类型,进而执行不一样的业务处理流程),好比前置的检查和校验步骤、构造MessageExtBrokerInner对象、decode反序列化、构造Response返回对象等。
主要指的是部署RocketMQ服务器所用的磁盘。这里,须要考虑不一样磁盘类型(如SSD或者普通的HDD)特性以及磁盘的性能参数(如IOPS、吞吐量和访问时延等指标)对顺序写/随机读操做带来的影响。
在RocketMQ中消息刷盘主要能够分为同步刷盘和异步刷盘两种。
1.Producer 发送消息,消息从 socket 进入 java 堆。
2.Producer 发送消息,消息从 java 堆转入 PAGACACHE,物理内存。
3.Producer 发送消息,由异步线程刷盘,消息从 PAGECACHE 刷入磁盘。
4.Consumer 拉消息(正常消费),消息直接从 PAGECACHE(数据在物理内存)转入 socket,到达 consumer, 不通过 java 堆。这种消费场景最多,线上 96G 物理内存,按照 1K 消息算,能够在物理内存缓存 1 亿条消 息。
5.Consumer 拉消息(异常消费),消息直接从 PAGECACHE(数据在虚拟内存)转入 socket。
6.Consumer 拉消息(异常消费),因为 Socket 访问了虚拟内存,产生缺页中断,此时会产生磁盘 IO,从磁 盘 Load 消息到 PAGECACHE,而后直接从 socket 发出去。
7.同 5 一致。
8.同 6 一致。
欢迎你们关注,你们一块儿学习,一块儿讨论。