RocketMQ源码分析之Message消费与拉取(下Consume的拉取消费)

本文深入探讨RocketMQ的PushConsumer订阅流程,详细解释了如何进行消息队列分配,包括Rebalance机制及广播与集群模式的差异。接着分析PushConsumer如何拉取消息,以及消息如何被消费,重点关注ConsumeMessageConcurrentlyService的角色。
摘要由CSDN通过智能技术生成

各组件大致功能图

这里写图片描述

PushConsumer订阅

DefaultPushConsumerImpl#subscrible
首先会创建订阅数据,在里面会根据topic、和订阅表达式将订阅信息放入到SubscriptionInner中,然后通过加分布式锁的方式进行心跳同步Consumer信息到所有的Broker

1: public void subscribe(String topic, String subExpression) throws MQClientException {
   
  2:     try {
   
  3:         // 创建订阅数据
  4:         SubscriptionData subscriptionData = FilterAPI.buildSubscriptionData(this.defaultMQPushConsumer.getConsumerGroup(), //
  5:             topic, subExpression);
  6:         this.rebalanceImpl.getSubscriptionInner().put(topic, subscriptionData);
  7:         // 通过心跳同步Consumer信息到Broker
  8:         if (this.mQClientFactory != null) {
   
  9:             this.mQClientFactory.sendHeartbeatToAllBrokerWithLock();
 10:         }
 11:     } catch (Exception e) {
   
 12:         throw new MQClientException("subscription exception", e);
 13:     }
 14: }

PushConsumer消息队列分配(Reblance)

在消费队列负载均衡服务中,负责分配当前Consumer可消费的消息队列
当等待超时(20s)或者PushCo启动或者有Consum加入移除的时候,会引MQClientInstance#doRebalance(…) 分配消息队列【该方法中,会遍历当前的Cient下的消费者集合表,并分别让每个MQComsumerInner执行doRelance均衡任务】
MQClientInstance#doRebalance(…)

  1: public void doRebalance() {
   
  2:     for (Map.Entry<String, MQConsumerInner> entry : this.consumerTable.entrySet()) {
   
  3:         MQConsumerInner impl = entry.getValue();
  4:         if (impl != null) {
   
  5:             try {
   
  6:                 impl.doRebalance();
  7:             } catch (Throwable e) {
   
  8:                 log.error("doRebalance exception", e);
  9:             }
 10:         }
 11:     }
 12: }

RebalanceImpl#rebalanceByTopic(…)
两种模式,一种是广播模式,一种是集群模式,如果是广播模式,则会分配Topic对应的所有的消息队列;如果是集群模式,会分配对应的部分消费队列【内部需要用Collections.sort队消息队列和消费者数组进行排序,这样才能保证各个Consumer顺序一致,并且会根据相应的队列分配策略分配队列,最后会更新Topic对应的消息队列】

  1: private void rebalanceByTopic(final String topic, final boolean isOrder) {
   
  2:     switch (messageModel) {
   
  3:         case BROADCASTING: {
   
  4:             Set<MessageQueue> mqSet = this.topicSubscribeInfoTable.get(topic);
  5:             if (mqSet != null) {
   
  6:                 boolean changed = this.updateProcessQueueTableInRebalance(topic, mqSet, isOrder);
  7:                 if (changed) {
   
  8:                     this.messageQueueChanged(topic, mqSet, mqSet);
  9:                     log.info("messageQueueChanged {} {} {} {}", //
 10:                         consumerGroup, //
 11:                         topic, //
 12:                         mqSet, //
 13:                         mqSet);
 14:                 }
 15:             } else {
   
 16:                 log.warn("doRebalance, {}, but the topic[{}] not exist.", consumerGroup, t
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值