rocketmq消息消费
消息获取
rocketmq中consumer有两种消息获取模式,分别是pull和push。
push模式指MQ主动向消费端推送消息。
pull模式指消费端消费时主动到MQ拉取消息。
本质上,两种模式都是消费端主动到MQ拉取消息,push模式只不过是pull模式的封装。其本质实现为消息拉取线程在从服务器拉取到一批消息后,然后提交到消息消费线程池后,又“马不停蹄”的继续向服务器再次尝试拉取消息。如果未拉取到消息,则延迟一下又继续拉取。
Consumer端每隔一段时间主动向broker发送拉消息请求,broker在收到Pull请求后,如果有消息就立即返回数据,Consumer端收到返回的消息后,再回调消费者设置的Listener方法。如果broker在收到Pull请求时,消息队列里没有数据,broker端会阻塞请求直到有数据传递或超时才返回。
当然,Consumer端是通过一个线程将阻塞队列LinkedBlockingQueue
broker在启动时,会启动一个线程不停的从ConcurrentHashMap取出PullRequest检查,直到有数据返回。
消息消费模式
Consumer端有两种消息消费模式,集群消费模式和广播消费模式。
集群:消费者集群:使用相同Group ID的订阅者属于同一个集群。同一个集群下的订阅者消费逻辑必须完全一致(包括 Tag 的使用),这些订阅者在逻辑上可以认为是一个消费节点,这些属于一个订阅者组。
集群消费模式
当使用集群消费模式时,MQ认为任意一条消息只需要被集群内的任意一台消费者处理即可。
集群消费模式下,相同Consumer Group的每个Consumer实例平均分摊消息。
广播消费模式
广播消费模式下,相同Consumer Group的每个Consumer实例都接收全量的消息。
当使用广播消费模式时,MQ会每条消息推送给集群内所有注册过的机器消费,保证每台机器至少消费一次。
一条消息被多个Consumer消费,即使这些Consumer属于同一个Consumer Group,消息也会被Consumer Group中的每个Consumer都消费一次。在广播消费中的Consumer Group概念可以认为在消息划分方面无意义。
注意事项
集群模式
- 消费端集群化部署,每条消息只消费一次。
- 消费进度维护再MQ中,更加可靠。
- 每一条消息都只会被分发到一台机器上处理。如果需要被集群下的每一台机器都处理,请使用广播模式。
- 不保证每一次失败重试的消息路由到同一台机器上,因此处理消息时不应该做任何确定性假设。
广播模式
- 广播模式下不支持顺序消息。
- 广播模式下不支持重置消费位点。
- 每条消息都需要被相同逻辑的多台机器处理。
- 消费进度在客户端维护,出现重复的概率稍大于集群模式。
- 消息队列RocketMQ保证每条消息至少被每台客户端消费一次,但是并不会对消费失败的消息进行失败重投,因此业务方需要关注消费失败的情况。
- 客户端每一次重启都会从最新消息消费。客户端在被停止期间发送至服务端的消息将会被自动跳过,请谨慎选择。
- 每条消息都会被大量的客户端重复处理,因此推荐尽可能使用集群模式。
- 目前仅 Java 客户端支持广播模式。
- 广播模式下MQ不维护消费进度,所以消息队列 RocketMQ 控制台不支持消息堆积查询、消息堆积报警和订阅关系查询功能。
使用集群模式模拟广播模式
将原来同一个消费者组的下消费者,拆分成每个消费者一个消费者组,这样就有很多个消费者组。
每个消费者组都订阅需要发送的消息,这样消息会发给每个消费者组,发给了每台机器,都可以消费。