RocketMQ 消息者(一) Consumer端架构 (图解)
RocketMQ 消息者(一) Consumer端架构 (图解)
1.配置项
Consumer 采用门面模式, 其门面类为 DefaultMQPushConsumer , 核心业务类为:DefaultMQPushConsumerImpl。
其中 DefaultMQPushConsumer 门面类中包含了 Consumer端的配置属性。
可配置的属性:
基本配置:
- consumerGroup: 消费者组
- messageModel: 消费模式 (默认 集群模式)
- allocateMessageQueueStrategy: 负载均衡策略
- messageListener: 业务层的消息监听器(其中的回调方法专门用来处理开发人员业务逻辑的)
- consumeThreadMin: 消费服务线程池 线程数最小值 (默认 20)
- consumeThreadMax: 消费服务线程池 线程数最大值 (默认 20)
流控配置:
- consumeConcurrentlyMaxSpan: 本地队列快照内,第一条消息和最后一条消息的offset跨度 不能超过 默认值 2000
- pullThresholdForQueue: 本地快照队列内, 消息数量限制 默认值 1000
- pullThresholdSizeForQueue: 本地快照队列内 消息size限制 默认值 100MB
- pullThresholdForTopic: 消费者消费的指定主题的所有消息,不能超过该值 默认值 -1 表示不限制
- pullThresholdSizeForTopic: 消费者消费的指定主题的所有消息大小限制 , 默认值 -1 表示不限制
- pullInterval: 两次向Broker端拉取消息请求的时间间隔 默认值 0
- consumeMessageBatchMaxSize: 消费任务 最多可消费的消息数量 (默认值 1 表示 每一个消费任务 只消费一条消息)
- pullBatchSize: 一次拉请求,最多可以从Broker拉取的消息数量 默认值 32
- postSubscriptionWhenPull: 向Broker拉取消息时, 是否提交本地 “订阅数据” 默认值 false
- maxReconsumeTimes: 最大重试消费次数 默认值 -1 表示可重试16次
- consumeTimeout: 消息在本地的超时时间,(默认值 15min 表示 某条消息 15min 内还未被消费,则该消息需要回退)
数据属性:
- subscription : 主题订阅信息集合 key: topic value: tag表达式
- offsetStore: 消费者本地消息消费进度 。 (记录 该消费者本地 订阅的所有mq 的消费进度)
2. 启动流程
Consumer端 的 核心启动 业务代码 在 DefaultMQPushConsumerImpl类中。
大致的启动流程如下图所示:
-
配置校验
this.checkConfig();
该过程主要就是检查 门面类 DefaultMQPushConsumer 中的属性配置值是否合法。
-
获取客户端实例 MQClientInstance
this.mQClientFactory = MQClientManager.getInstance().getOrCreateMQClientInstance(this.defaultMQPushConsumer, this.rpcHook);
注意: 这里客户端实例 同一个JVM进程内,只有一个客户端实例
该 客户端实例 底层是 Netty客户端, 其架构设计 会在 RocketMQ服务端和客户端的架构设计 这篇文章中详细介绍。
-
初始化负载均衡对象 RebalancePushImpl
初始化的工作如下:
- 设置消费者组
- 设置消费模式 (默认 集群模式)
- 设置 负载均衡的核心算法 AllocateMessageQueueStrategy
- 设置 客户端实例对象
注意: 每个消费者端都会有自己的一个负载均衡对象,而控制整个负载均衡服务的入口 在 客户端实例中。 客户端的负载均衡服务 会遍历 所有的消费者端 让他们执行各自的负载均衡方法。
-
创建和初始化 拉消息对象 PullAPIWrapper
注意:与 负载均衡一样, 每个消费者端都会有自己的 拉消息对象, 而总的拉消息服务入口 在 客户端实例中。
-
根据 配置的消费消息监听器类型,来决定创建 和 启动 哪种 消费消息服务 ConsumeMessageService。
消费消息服务有两种:
- ConsumeMessageConcurrentlyService :并发消费消息服务
- ConsumeMessageOrderlyService : 顺序消费消息服务
- 向 客户端实例 中 注册该消费者。
mQClientFactory.registerConsumer(this.defaultMQPushConsumer.getConsumerGroup(), this);
客户端实例中,consumerTable 是专门用来维护 所有消费者 的映射表。
- 向 Broker 节点 发送心跳, 维护与Broker服务器的连接。
this.mQClientFactory.sendHeartbeatToAllBrokerWithLock();
3. 本地维护的数据
消费者端 所消费的数据 是主动从 Broker服务器上拉取的, 而拉下来的数据会在消费者本地存储下来, 并记录每次消费的进度 并将该进度 同步给Broker服务器。
这里 就介绍下 消费者 本地 会维护哪些 数据
1.subscription
该 数据结构 是在 门面类 DefaultMQPushConsumer 中维护的, 主要存储的是 topic 与 tag 的映射关系。
2.offsetTable
该数据结构位于 RemoteBrokerOffsetStore 类中, 主要是 消费者本地来 存储和记录 消息的消费进度。
3.processQueueTable
该 数据结构 是在 负载均衡 RebalanceImpl 对象中, 是消费者端的核心数据结构, 存储的是 分配到该消费者的队列queue 的详细信息 (其中包括 队列中的消息数据)。
4.topicSubscribeInfoTable
该 数据结构 是在 负载均衡 RebalanceImpl 对象中, 主要存储的是 该消费者 所关注的 topic主题 的 队列分布情况。
5.subscriptionInner
protected final ConcurrentMap<String /* topic */, SubscriptionData> subscriptionInner =
new ConcurrentHashMap<String, SubscriptionData>();
该数据结构 是在 负载均衡 RebalanceImpl 对象中, 主要存储的是 消费者订所订阅的 topic 与 订阅信息的映射关系。 实际上就可以理解成 与subscription 类似的作用。
6.pullFromWhichNodeTable
该数据结构 位于 拉消息对象 PullAPIWrapper 中, 主要存储 下次 拉取目标队列消息 要 去 哪个broker 上拉。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)