版本声明
- 基于
rocketmq-all-4.3.1
版本
消费模式
- 消费组
- 一个消费组可以包含多个Consumer,一个消费组可以订阅多个Topic
- 消费组之间有集群和广播两种消费模式,集群模式下,Topic中的同一条消息只允许被其中一个Consumer消费。广播模式下,Topic中的同一条消息可以被集群中的所有Consumer消费。
- 消费模式
- 拉模式:消息到达Broker后,Consumer主动发起拉取请求
- 推模式:消息达到Broker后,由Broker推送给Consumer。RocketMQ中推模式的实现是基于拉模式,即一个拉取任务完成后开始下一个拉取任务
- 集群模式下,多个Consumer需要对消息队列进行负载均衡。一个消息队列同时只允许被一个Consumer消费,一个Consumer可以消费多个消息队列。
推模式消费
-
DefaultMQPushConsumer是推模式核心入口类,主要委托DefaultMQPushConsumerImpl实现相关功能。RocketMQ并没有真正实现推模式,而是Consumer主动向消息服务器拉取消息,RocketMQ推模式是循环向Broker端发送消息拉取请求。
-
DefaultMQPushConsumer核心属性如下
public class DefaultMQPushConsumer extends ClientConfig implements MQPushConsumer { //委托类,大部分操作都是委托DefaultMQPushConsumerImpl protected final transient DefaultMQPushConsumerImpl defaultMQPushConsumerImpl; //消费组 private String consumerGroup; // 消息消费模式,分为集群模式、广播模式,默认为集群模式。 private MessageModel messageModel = MessageModel.CLUSTERING; /** 第一次消费时指定消费策略 CONSUME_FROM_LAST_OFFSET:此处分为两种情况,如果磁盘消息未过期且未被删除,则从最小偏移量开始消费。如果磁盘已过期并被删除,则从最大偏移量开始消费。 CONSUME_FROM_FIRST_OFFSET:从队列当前最小偏移量开始消费。 CONSUME_FROM_TIMESTAMP:从消费者指定时间戳开始消费。 如果从消息进度服务OffsetStore读取到MessageQueue中的偏移量不小于0,则使用读取到的偏移量拉取消息,只有在读到的偏移量小于0时,上述策略才会生效。 **/ private ConsumeFromWhere consumeFromWhere = ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET; private String consumeTimestamp = UtilAll.timeMillisToHumanString3(System.currentTimeMillis() - (1000 * 60 * 30)); // 集群模式下消息队列的负载策略 private AllocateMessageQueueStrategy allocateMessageQueueStrategy; // 订阅信息 private Map<String /* topic */, String /* sub expression */> subscription = new HashMap<String, String>(); // 消息业务监听器。 private MessageListener messageListener; // 消息消费进度存储器。 private OffsetStore offsetStore; // 费者最小线程数 private int consumeThreadMin = 20; // 消费者最大线程数 private int consumeThreadMax = 64; private long adjustThreadPoolNumsThreshold = 100000; //并发消息消费时处理队列最大跨度 private int consumeConcurrentlyMaxSpan = 2000; //每1000次流控后打印流控日志 private int pullThresholdForQueue = 1000; private int pullThresholdSizeForQueue = 100; private int pullThresholdForTopic = -1; private int pullThresholdSizeForTopic = -1; // 推模式下拉取任务的间隔时间 private long pullInterval = 0; //消息并发消费时一次消费消息的条数 private int consumeMessageBatchMaxSize = 1; //每次消息拉取的条数 private int pullBatchSize = 32; // 是否每次拉取消息都更新订阅信息,默认为false。 private boolean postSubscriptionWhenPull = false; /** * Whether the unit of subscription group */ private boolean unitMode = false; // 最大消费重试次数 private int maxReconsumeTimes = -1; // 延迟将该队列的消息提交到消费者线程的等待时间,默认延迟1s private long suspendCurrentQueueTimeMillis = 1000; // 息消费超时时间 private long consumeTimeout = 15;
启动流程
-
DefaultMQPushConsumer启动就是委托DefaultMQPushConsumerImpl来实现的
@Override public void start() throws MQClientException { this.defaultMQPushConsumerImpl.start(); }
-
DefaultMQPushConsumerImpl启动流程图
-
启动源码
public synchronized void start() throws MQClientException { switch (this.serviceState) { case CREATE_JUST: log.info("the consumer [{}] start beginning. messageModel={}, isUnitMode={}", this.defaultMQPushConsumer.getConsumerGroup(), this.defaultMQPushConsumer.getMessageModel(), this.defaultMQPushConsumer.isUnitMode()); this.serviceState = ServiceState.START_FAILED; //1. 检查配置 this.checkConfig(); //2. 构建订阅SubscriptionData信息,并加入到RebalanceImpl的订阅消息中 this.copySubscription(); if (this.defaultMQPushConsumer.getMessageModel() == MessageModel.CLUSTERING) { this.defaultMQPushConsumer.changeInstanceNameToPID(); } //3. 实例化MQClientInstance this.mQClientFactory = MQClientManager