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类中。

大致的启动流程如下图所示:

  1. 配置校验

    this.checkConfig();
    

    该过程主要就是检查 门面类 DefaultMQPushConsumer 中的属性配置值是否合法。

  2. 获取客户端实例 MQClientInstance

this.mQClientFactory = MQClientManager.getInstance().getOrCreateMQClientInstance(this.defaultMQPushConsumer, this.rpcHook);

注意: 这里客户端实例 同一个JVM进程内,只有一个客户端实例

客户端实例 底层是 Netty客户端, 其架构设计 会在 RocketMQ服务端和客户端的架构设计 这篇文章中详细介绍。

  1. 初始化负载均衡对象 RebalancePushImpl

    初始化的工作如下:

    • 设置消费者组
    • 设置消费模式 (默认 集群模式)
    • 设置 负载均衡的核心算法 AllocateMessageQueueStrategy
    • 设置 客户端实例对象

    注意: 每个消费者端都会有自己的一个负载均衡对象,而控制整个负载均衡服务的入口 在 客户端实例中。 客户端的负载均衡服务 会遍历 所有的消费者端 让他们执行各自的负载均衡方法。

  2. 创建和初始化 拉消息对象 PullAPIWrapper

    注意:与 负载均衡一样, 每个消费者端都会有自己的 拉消息对象, 而总的拉消息服务入口 在 客户端实例中。

  3. 根据 配置的消费消息监听器类型,来决定创建 和 启动 哪种 消费消息服务 ConsumeMessageService

消费消息服务有两种:

  • ConsumeMessageConcurrentlyService :并发消费消息服务
  • ConsumeMessageOrderlyService : 顺序消费消息服务
  1. 向 客户端实例 中 注册该消费者。
 mQClientFactory.registerConsumer(this.defaultMQPushConsumer.getConsumerGroup(), this);

客户端实例中,consumerTable 是专门用来维护 所有消费者 的映射表。

  1. 向 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 上拉。

posted @ 2022-03-11 13:30  s686编程传  阅读(720)  评论(0编辑  收藏  举报