多数消息队列中,消费者和 Broker 通信的方式有两种, PUSH 模式和 PULL 模式:
-
PUSH 模式:Broker 主动把消息推送给订阅的消费者;
-
PULL模式: 消费者主动从 Broker 拉取消息。
注意,RocketMQ 并没有真正实现 PUSH 模式, RocketMQ 中的 PUSH 模式,本质上也是 PULL 模式,只是消费端封装了轮询过程,相当于开启一个定时线程不停地从 Broker 拉取消息,拉取到消息后唤醒本地业务线程来处理。 本文讲解 PULL 模式 的启动过程。涉及到到的启动过程如下图:
首先看下面这张图:
图中可以看出,消费者需要注册到 Name Server,拉取消息的时候可以从 Broker 主节点拉取,也可以从 Broker 从节点拉取。
在 RocketMQ 的源码中,拉模式有两个消费者相关的类,其中 DefaultMQPullCons umer 类已经被废弃,官方推荐使用 Defau ltLitePullConsumer 类。下面代码来自官方示例:
public static void main(String[] args) throws Exception { DefaultLitePullConsumer litePullConsumer = new DefaultLitePullConsumer("lite_pull_consumer_test"); litePullConsumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET); litePullConsumer.subscribe("TopicTest", "*"); //启动方法 litePullConsumer.start(); try { while (running) { //这里可以看到,PULL 模式下消费者需要业务代码主动去拉取消息 List<MessageExt> messageExts = litePullConsumer.poll(); System.out.printf("%s%n", messageExts); } } finally { litePullConsumer.shutdown(); } }
上面代码中消费者属于消费组 lite_pull _consumer_test,订阅了【TopicTest 】这个 Topic 下的所有 tag。下面一起看一下启动方法。下图是消费者启动过程中类调用关系图,图中心的 pullRequestQueu e 是核心,pull 请求会先发送到这个队列,然后循环地拉取处理。