【RocketMQ】记录一次RocketMQ消费延迟问题排查思路

文章目录

背景

业务团队反馈使用我提供的RocketMQ集群,上游生产的消息,部分消息,消费程序需要等1分钟,甚至几分钟后,才能收到。

问题排查

见怪不怪,大部分的问题,都是和客户端的使用上有关系,根据一番了解,业务方是这样写消费者程序的:

  1. 消费者使用拉模式;
  2. 消费者有3个实例;
  3. 使用了XXL-JOB做任务调度,每分钟执行一次,触发消费者的拉取操作
  4. XXL-JOB使用的是轮询的调度方式。

到这里,如果了解RocketMQ消费者机制的,应该已经知道问题了,下面是简单的思路总结:

  1. RocketMQ创建Topic时会有队列数的配置,类似于Kafka的Partition;
  2. 例如:RocketMQ集群有3个Broker,创建Topic时设置读队列数为16,这个Topic的总的消费队列为48;
  3. 所有消费者实例会近似平均地去负责这48个队列,也就是说,每隔1分钟,用轮询的方式去执行消费,每次只会消费到topic中1/3的消息,下一次JOB执行,才会继续消费,这中间JOB执行的间隔,就导致了消费的延迟。

下面详细说一下RocketMQ消费者的负载均衡机制。

Consumer负载均衡机制

集群模式下,同一个消费组内的消费者会分担收到的全量消息,这里的分配策略是怎样的?如果扩容消费者是否一定能提升消费能力?

Apache RocketMQ 提供了多种集群模式下的分配策略,包括平均分配策略、机房优先分配策略、一致性hash分配策略等,可以通过如下代码进行设置相应负载均衡策略。

java 复制代码
consumer.setAllocateMessageQueueStrategy(new AllocateMessageQueueAveragely());

默认的分配策略是平均分配,这也是最常见的策略。平均分配策略下消费组内的消费者会按照类似分页的策略均摊消费。

在平均分配的算法下,可以通过增加消费者的数量来提高消费的并行度。比如下图中,通过增加消费者来提高消费能力。

从一个消费者,扩到两个消费者:

从3个扩到4个:

但也不是一味地增加消费者就能提升消费能力的,比如下图中Topic的总队列数小于消费者的数量时,消费者将分配不到队列,即使消费者再多也无法提升消费能力。

在RocketMQ中每个队列都会记录自己的最小位点、最大位点。针对于消费组,还有消费位点的概念,在集群模式下,消费位点是由客户端提给交服务端保存的,在广播模式下,消费位点是由客户端自己保存的。一般情况下消费位点正常更新,不会出现消息重复,但如果消费者发生崩溃或有新的消费者加入群组,就会触发重平衡,重平衡完成后,每个消费者可能会分配到新的队列,而不是之前处理的队列。为了能继续之前的工作,消费者需要读取每个队列最后一次的提交的消费位点,然后从消费位点处继续拉取消息。但在实际执行过程中,由于客户端提交给服务端的消费位点并不是实时的,所以重平衡就可能会导致消息少量重复。

订阅关系的一致

再补充一点,也是很多业务方会忽略的一个问题,很多用户为了方便,或者不经意间,会用一个消费组去消费多个topic,这样也是会存在问题的。

同一个消费者组(Group ID相同)下所有Consumer实例所订阅的Topic与Tag及对消息的处理逻辑必须完全一致。否则,消息消费的逻辑就会混乱,甚至导致消息丢失。

相关推荐
明洞日记5 分钟前
【设计模式手册007】原型模式 - 通过复制创建对象的艺术
java·设计模式·原型模式
源码君miui5208626 分钟前
JAVA国际版同城服务同城信息同城任务发布平台APP源码Android + IOS
android·java·ios
鹿衔`44 分钟前
解决Flink on Yarn模式多Yarn Session会话提交
java·前端·flink
静若繁花_jingjing1 小时前
SpringBoot/SpringMvc/SpringCloud
java·spring boot·spring cloud
q***04631 小时前
【springboot】Spring 官方抛弃了 Java 8!新idea如何创建java8项目
java·spring boot·spring
稚辉君.MCA_P8_Java1 小时前
Sqoop 实现的功能是什么
java·服务器·架构·kubernetes·sqoop
w***4811 小时前
【Spring】IDEA中创建Spring项目
java·spring·intellij-idea
Thexhy1 小时前
Java大模型后端开发全流程指南
java·ai·大模型
從南走到北2 小时前
JAVA同城服务场馆预约门店预约健身房瑜伽馆预约系统支持H5小程序APP源码
java·开发语言·小程序
爱学的小码2 小时前
JavaEE初阶——多线程3(案例)
java·开发语言·单例模式·java-ee