rocketmq消息消费

消息获取

  rocketmq中consumer有两种消息获取模式,分别是pull和push。

  push模式指MQ主动向消费端推送消息。
  pull模式指消费端消费时主动到MQ拉取消息。
  本质上,两种模式都是消费端主动到MQ拉取消息,push模式只不过是pull模式的封装。其本质实现为消息拉取线程在从服务器拉取到一批消息后,然后提交到消息消费线程池后,又“马不停蹄”的继续向服务器再次尝试拉取消息。如果未拉取到消息,则延迟一下又继续拉取。
  Consumer端每隔一段时间主动向broker发送拉消息请求,broker在收到Pull请求后,如果有消息就立即返回数据,Consumer端收到返回的消息后,再回调消费者设置的Listener方法。如果broker在收到Pull请求时,消息队列里没有数据,broker端会阻塞请求直到有数据传递或超时才返回。
  当然,Consumer端是通过一个线程将阻塞队列LinkedBlockingQueue中的PullRequest发送到broker拉取消息,以防止Consumer一致被阻塞。而Broker端,在接收到Consumer的PullRequest时,如果发现没有消息,就会把PullRequest扔到ConcurrentHashMap中缓存起来。
  broker在启动时,会启动一个线程不停的从ConcurrentHashMap取出PullRequest检查,直到有数据返回。


消息消费模式

  Consumer端有两种消息消费模式,集群消费模式和广播消费模式。
  集群:消费者集群:使用相同Group ID的订阅者属于同一个集群。同一个集群下的订阅者消费逻辑必须完全一致(包括 Tag 的使用),这些订阅者在逻辑上可以认为是一个消费节点,这些属于一个订阅者组。

集群消费模式

  当使用集群消费模式时,MQ认为任意一条消息只需要被集群内的任意一台消费者处理即可。
  集群消费模式下,相同Consumer Group的每个Consumer实例平均分摊消息。

集群模式消费

广播消费模式

  广播消费模式下,相同Consumer Group的每个Consumer实例都接收全量的消息。
  当使用广播消费模式时,MQ会每条消息推送给集群内所有注册过的机器消费,保证每台机器至少消费一次。
  一条消息被多个Consumer消费,即使这些Consumer属于同一个Consumer Group,消息也会被Consumer Group中的每个Consumer都消费一次。在广播消费中的Consumer Group概念可以认为在消息划分方面无意义。 

广播模式消费

注意事项

集群模式

  1. 消费端集群化部署,每条消息只消费一次。
  2. 消费进度维护再MQ中,更加可靠。
  3. 每一条消息都只会被分发到一台机器上处理。如果需要被集群下的每一台机器都处理,请使用广播模式。
  4. 不保证每一次失败重试的消息路由到同一台机器上,因此处理消息时不应该做任何确定性假设。

广播模式

  1. 广播模式下不支持顺序消息。
  2. 广播模式下不支持重置消费位点。
  3. 每条消息都需要被相同逻辑的多台机器处理。
  4. 消费进度在客户端维护,出现重复的概率稍大于集群模式。
  5. 消息队列RocketMQ保证每条消息至少被每台客户端消费一次,但是并不会对消费失败的消息进行失败重投,因此业务方需要关注消费失败的情况。
  6. 客户端每一次重启都会从最新消息消费。客户端在被停止期间发送至服务端的消息将会被自动跳过,请谨慎选择。
  7. 每条消息都会被大量的客户端重复处理,因此推荐尽可能使用集群模式。
  8. 目前仅 Java 客户端支持广播模式。
  9. 广播模式下MQ不维护消费进度,所以消息队列 RocketMQ 控制台不支持消息堆积查询、消息堆积报警和订阅关系查询功能。

使用集群模式模拟广播模式

  将原来同一个消费者组的下消费者,拆分成每个消费者一个消费者组,这样就有很多个消费者组。
  每个消费者组都订阅需要发送的消息,这样消息会发给每个消费者组,发给了每台机器,都可以消费。

集群模式模拟广播模式