RocketMQ特性

1、为什么需要消息队列

削峰填谷

程序间解耦

异步处理

数据的最终一致性

2、常见消息队列

消息队列 activeMQ kafka rocketMQ

特性

支持多种协议:AMQP、STMOP、MQTT、JMS

消息支持持久化

超高写入速率

端到端耗时毫秒级

万亿级消息支持

万级topic数量支持

端到端耗时毫秒级

管理后台 自带 独立部署 独立部署
多语言支持 支持 支持 java、c++、python、go、c#
数据流支持 不支持 支持 支持
消息丢失 理论上不丢失 理论上不丢失 理论上不丢失
文档完整性 极好 极好
商业化公司 国内部分企业 国内很多企业 阿里巴巴为主
容错 无重试机制 无重试机制 支持重试、死信消息
顺序消息 支持 支持 支持
定时消息 不支持 支持 支持
事务消息 不支持 不支持 支持
消息查询 数据库中查询 不支持 支持
宕机 自动切换 主动选主 手动重启

3、生产者

生产者组:一个生产者生产多个topic消息

生产者实例:一个生产者部署多个进程,每个进程都可以称为一个生产者实例

topic:主题名称,一个topic由若干个queue组成

4、消息组成

topic

properties:消息扩展信息,Tag、Keys、延迟级别都保持在这里

Body:消息体,字节数组,需要注解编码格式保持一致,防止消息乱码

setKeys:设置消息的key,可以根据key常见消息的hash索引,帮助快速查询

setTags:设置tag,一个topic可以设置不同的tag

setDelayTimeLevel:设置消息延迟级别

putUserProperty:如果有其他要扩展的信息,可以放在这个Map中

5、消息支持类型

普通消息:性能最好

分区有序消息:一个topic对应多个分区,分区使用FIFO原则

全局有序消息:一个topic对应一个分区

延迟消息:消息发送后一段时间后,消费者才可以被消费掉

事务消息:可以保证多个事务同时成功或者失败,机制时half消息、处理本地事务、提交消息、回滚消息的方式实现优雅的分布式事务

6、生产者高可用

客户端保证

重试机制:rocketMQ支持同步、异步方式,都可以在失败后重试,如果一个broker发生故障,可以找到其他可用的broker

客户端容错:客户端可以选择延迟级别最低的broker进行发送消息

Broker保证

数据同步分为同步复制、异步复制两种。

同步复制是指消息发送到master broker后,同步到slave broker才算发送成功。

异步复制是指消息发送到master broker后就算成功。

如果是多个master slave也是类似的方式。

如果想要保持绝对的高可用,将broker配置的主从同步进行复制即可,只要生产者收到消息保持成功就反馈,消息可定不会丢失。

7、消息发送流程

业务层:直接调用rocketMQ client 发送api的业务代码

消息处理层:rocketMQ client 获取业务发送的消息对象后,进行的一些列参数校验、发送准备、参数包装等操作

通信层:rocketMQ基于netty封装的一个rpc通讯协议

8、延迟消息

支持18个级别,从1S、5S、10S、30S、1M、2、3、4、5、6、7、8、9、10、20、30、1h、2h

9、事务消息

第一步先发送一个half消息到broker,Broker设置queueOffset=0,即对消费者不可见

第二笔用户本地事务提交成功后,发送一个commit到broker,broker修改queueoffset为正数值,达到投递目的,如果本地事务提交失败,则发送一个rollback消息给broker。

broker会定期回查生产者,确认生产者本地事务的执行状态,再决定是提交还是回顾还是删除half消息。

10、发送单向消息

主要是日志传输等消息允许丢失的常见

11、批量消息

消息最好小于1M

同一批消息的topic、waitStoreMsgOk属性必须一致

批量消息不支持延迟消息

12、生产者最佳实践

普通消息:性能最好、单机TPS10万级别,缺点是生产和消费都是无须、适用于大部分场景

分区消息:单机有序、单机TPS万级别、缺点是单点问题、如果broker宕机会导致消息发送失败、适用于大部分有序消息场景

 全局有序消息:类型传统queue、单机TPS千级别、单点问题、如果broker宕机会导致消息发送失败、适用场景极少

延迟消息:rocketMQ自身支持、不需要额外组件、缺点是不能根据任意时间延迟、非精确、延迟级别不够多、使用简单方便

事务消息:rocketMQ自身支持、不需要额外组件、缺点是生产者事务、只有生产者参与,如果消费者处理失败则事务无效、简单事务处理可以使用

13、同步与异步发送

同步发送:最可靠、性能最低、适用于高并发常见

异步发送:可靠、性能最高、如果发送失败需要考虑降级、大部分业务场景可以使用

14、常见配置参数

producerGroup生产者分组

消息体数量超过该值则压缩消息

instanceName生产者实例名

maxMessageSize消费体最大值,默认4M

retryXXX异步发送失败的重试次数

retryTimsWhenSendFailed同步发送失败的重试次数

senMsgTimeout发送超时时间

15、消费者概念

消费者组:一个逻辑概念,在使用消费者时要指定一个分组,一个消费者组可以订阅多个topic

消费者实例:一个消费者程序部署多个进程,每个进程都可以称为一个消费者实例

订阅关系:一个消费者组订阅一个topic的某个tag、这种记录被称为订阅关系,消费者分组-topic-tag必须是唯一的

16、消费模式

集群消费与广播消费

集群消费

同一个消费者分组了里的消费者实例,会负载均衡的消费topic

同一个topic会被不同的消费者分组里的消费者实例消费,即1个topic关联多个消费者分组

集群消费的进度保存在broker端,所以即使应用崩溃、消费进度也不会丢失

广播模式

即消费者组中的全部消费者实例将消费整个topic的全部消息

一个消费者分组中的两个消费者实例,每个消费者实例消耗相同数量的topic消息,不会进行负载均衡

17、可靠消息

重试消费(做多16次)、死信机制(超过16次则放入死信队列)

死信队列:命名格式“%DLQ%消费者组名”

18、rebalance机制

重平衡机制,用于在发现broker掉线、topic扩容或者缩容、消费者扩容和缩容等变化时,自动感知并调整自身消费,尽力减少甚至避免消费没有被消费。

19、消费进度保存机制

rocketMQ设计了远程位点管理和本地位点管理两种位点管理方式

集群消费时,位点管理由客户端交给broker管理

广播模式下,位点保存在消费者本地磁盘上(即使丢失了,也可以重复消费)

20、消费方式push与pull

pull方式:用户主动pull消息,自主管理位点,可以灵活掌控消费进度、消费速度,缺点时需要从代码层面精准控制消费

push方式:代码接入简单、排查问题方便、适用于大部分常见,缺点是灵活度差

21、rocketMQ架构

console控制台:创建topic、key查询消费

namesrv:一个无状态的元数据管理、类似与kafka中zookeeper的定位

broker集群:保存消息、处理生产者、消费者的各种请求的代理,包括master和slave两个角色

生产者集群:消费发送方

消费者集群:消息消费方

22、namesrv

部署推荐2~3个节点

23、broker部署方式

单个master、单master单slave、多个master无slave、多个master多个slave异步复制、多个master多个slave同步复制

24、刷盘

消息保持到内存后,可以同步、异步方式写到磁盘上

同步刷盘:生产者等待写入磁盘才返回发送成功

异步刷盘:生产者写入内存就可以返回发送成功

25、namesrv

主要保持管理topic路由信息(topic队列信息、broker信息、集群和broker对应关系、当前在线的broker地址、过滤服务器信息)、各个namesrv是无状态的,多个namesrv之间不需要同步信息、状态

在broker、生产者、消费者启动时,可以轮训全部配置的namesrv节点、拉取路由信息

Topic路由信息决定了topic信息发送到哪个broker,消费者从哪个broker消费消息

26、namesrv与zookeeper

不适用zookeeper的原因是减少依赖,通过简单的namesrv可以承担

27、namesrv流程

broker启动注册到namesrv中

生产者询问namesrv把消息发送到哪里

namesrv告诉消息发送到的broker

生产者发送消息到broker

消费者询问namesrv在哪里可以消费信息

namesrv告诉消费者具体的broker

消费者向指定broker拉取消息

28、namesrv核心组件

topic路由管理模块:信息发送到哪个broker、从哪个broker消费

remoting通讯模块:netty的一个通讯封装

定时任务模块:扫描宕机的broker、定时打印kv配置、定时扫描超时请求

29、路由注册

namesrv获取的topic路由信息来自broker的定时心跳、心跳时broker会将topic信息发送到namesrv。

30、路由剔除

broker主动剔除

namesrv定时扫描已下线的broker

 31、消费过滤

RocketMQ设计了消息过滤:即对于客户端不需要的消息,Broker不会传输给客户端,以避免浪费。

使用Tag进行过滤消息

过滤步骤:

1、用户发送一个带有tag的消息

2、用户订阅一个topic的tag,RocketMQ broker会保持订阅关系

3、在Broker端做tag过滤。消费者pull时RocketMQ broker会根据tag的hashcode进行比较,如果不满足条,不会返回给消费者。

4、客户端tag过滤,由于hashcode存在碰撞问题,所以还以在客户端进行字符串比较

32、消息问题排查

1、topic是否一致:生产者、消费者、控制台

2、订阅关系是否一致

3、消费者是否抛出了异常,如果没有抛出异常,消息不会进行重试

4、消费者服务器与namesrv或者broker是否网络通畅

33、Broker存储机制

Broker主要负责处理各种tcp请求和存储消息

Broker分为master和slave,master主要提供服务,slave在master宕机后提供消费服务。

34、Broker存储目录结构

commitlog:目录下有多个文件,文件名有该文件保存消息的最大物理offset值在高位补0组成。文件大小一般1G。

consumequeue:目录下包含该broker上所有的topic对应的消费队列文件信息。

Index:目录下的全部文件都是按照消息key创建的hash索引。

config:目录保存了当前Broker中全部topic、订阅关系和消费进度。

35、Broker启动与停止

第一步:初始化启动环境,包括启动./bin/mqbroker和./bin/runbroker.sh两个脚本,设计到JAVA_HOME、ROCKETMQ_HOME环境变量。

第二步:初始化BrokerController:RocketMQ命令行解析、Broker各个模块配置参数解析、Broker各个模块初始化、进程关机hook初始化等过程。

第三步:启动RocketMQ的各个组件:存储服务、普通请求处理服务、VIP请求处理服务、Broker访问对外接口的封装对象、Pull长轮训服务、清理心跳超时的生产者和消费者和过滤服务、过滤服务器。

36、Broker存储机制

消息会存储到commitlog中,为了方便保存和读取会把commitlog切分为多个文件

Broker按照时间和物理的offset顺序写commitlog文件,每次写的时候需要加锁。

37、为什么写文件很快

参考了kafka的设计

Page Cache:分页读取文件、整页读取可以进行预读

VM:虚拟内存,把暂时不需要的数据保存到磁盘(虚拟内存)

零拷贝与Java文件映射:Java进程可以直接读取到内核态的数据,不需要经过用户态转换

38、Broker消息存储流程

业务系统发送信息

->broker接收到客户端消息进行预处理:解析参数、执行发送处理前的hook、调用保存方法存储消息、执行发送处理后的hook。

->broker存储前进行预处理:设置请求处理返回对象标识

->执行putMessage方法进行消息校验和存储模块检查:存储模块是否已关闭、Broker是否是slave、存储模块运行标识、topic长度、扩展信息长度等

39、文件刷盘机制

同步与异常刷盘:内存数据保持到磁盘

同步刷盘:有一个后台线程服务

异步刷盘:如果broker配置了读写分离,则异步刷盘过程包含异步转存数据和真正的异步刷盘操作。

40、Broker读写分离

master与slave读写分离

直接写内存与读PageCache分离

41、Broker commitlog索引机制

Broker有两个索引:consumer queue和Index File

consumer queue:消费者队列,用于消费者拉取信息、更新消费点

Index File:是一个RocketMQ实现的hash索引,用于用户根据key查询消息

42、Broker过期文件删除机制

commitlog文件删除:当前时间大于已经配置的过期时间、磁盘使用空间超过85%、手动执行删除

步骤一:克隆全部commitlog文件,为了防止有数据写入

步骤二:检查每个commitlog是否过期

43、broker主从同步机制

第一:broker服务高可用,一般生产环境部署两个master、两个slave节点,一个master宕机后,另个一master会继续工作。

第二:提供服务性能,如果消费者发现行master拉取信息时,拉取的offset和commitlog物理offset相差太多,会转向slave拉取消息。

同步复制、同步刷盘

44、生产者启动流程

创建一个生产者实例,设置各种参数,比如namesrv地址、生产者组名等,调用star()方法创建生产者实例。

判断当前生产者的服务状态,默认状态为CREATE_JUST

执行checkConfig方法

执行changeInstanceNameToPID方法

执行getAndCreateMQClientInstance方法

45、消息发送流程

调用defaultMQProducer.send()方法

设置超时时间

设置同步发送

发送前check:生产者状态、消息、消息内容

选择topic、queue发送:获取topic路由信息

计算信息发送的重试次数,同步重试或者异步重试

执行sendKernel方法

46、消费者启动机制

调用DefaultMQPullConsumer的start()方法

检查消费者的配置,消费者组名、消费类型、Queue分配策略

检验消费者实例名

获取一个MQClientInstance

设置rebalance对象消费者组、消费类型、Queue分配策略等

对Broker api的封装类进行初始化

初始化位点管理器,并加载位点信息

本地注册消费者实例

启动MQClientInstance

posted @ 2024-04-16 00:42  使用D  阅读(1)  评论(0编辑  收藏  举报