Kafka某个Topic无法消费问题

问题描述

12月28日,公司测试环境Kafka的task.build.metadata.flow这个topic突然无法消费。

其他topic都正常使用,这个topic只有一个分区,并且只有一个消费者

查找问题原因

首先登录服务器,运行kafka的cli命令,查看消费者组的详情。

# 进入kafka安装目录下的bin目录执行
./kafka-consumer-groups.sh --bootstrap-server 127.0.0.1:9092 --describe --group 消费者组名称

在这里插入图片描述
由上图可以发现,task.build.metadata.flow这个topic,最新offset是2,但是当前offset只到1,还有一条未消费。
并且该消费者组显示没有客户端正在消费这个topic。

查看项目日志发现以下内容:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述分析项目日志,可以看出:

  1. 消费者是消费过数据的(有一行日志打印)。但是日志中只发现过一次消费记录。
  2. 在项目没有重新发布,没有消费者增加,分区数没有改变的情况下,kafka执行过Rebalance机制。
什么是Rebalance:
Rebalance 本质上是一种协议,规定了一个 Consumer Group 下的所有 consumer 如何达成一致,来分配订阅 Topic 的每个分区。
简单来说,就是把 Topic 中所有的分区,按照一定的规则分配给 Consumer Group 下的所有 consumer。
例如:某 Group 下有 3 个 consumer 实例,它订阅了一个具有 9 个 partition 的 Topic。
正常情况下,kafka 会为每个 Consumer 平均的分配 3 个分区。这个分配的过程就是 Rebalance。
触发 Rebalance 的时机:
1. Consumer Group 中的 Consumer 数量发生变化时。
2. 订阅的 Topic 数量发生变化时。
3. 订阅 Topic 的分区发生变化时。
Rebalance 发生时,Group 下所有 consumer 实例都会协调在一起共同参与,kafka 能够保证尽量达到最公平的分配。
但是 Rebalance 过程对 consumer group 会造成比较严重的影响。
在 Rebalance 的过程中 consumer group 下的所有消费者实例都会停止工作,等待 Rebalance 过程完成

解决问题

首先,日志中显示项目曾经消费过这个topic,但是只消费一次,后续不再消费,并且之后kafka发生Rebalance。结合使用kafka cli命令查看的消费者组详情,分析出:

消费者第一次可以消费数据,但是由于某种原因,消费后,消费者下线,然后触发了Rebalance机制,导致后续使用cli查看消费者详情的时候,看不到这个topic有客户端。

基于这个思路,我们把项目中消费者的代码全部注释,只留一行日志记录。然后发布项目后,再次生产一条消息查看是否能够消费。
根据多次测试结果发现消费是正常的。
那么问题应该就出现在消费者的代码中了,应该是代码中的操作影响到了kafka,导致kafka进行Rebalance。

查阅Rebalance相关资料发现:
在这里插入图片描述

原文出处:https://blog.csdn.net/qq_21383435/article/details/108720155

因为涉及到的参数原理较多,这里简单描述下:
因为kafka要保证消费者一直在正常消费,所以加了心跳,超时等机制,用来判断消费者是否正常。
由于我们的消费者代码执行太慢,超时了,导致kafka服务端认为消费者已经挂掉,所以将这个消费者踢出。
踢出消费者后,因为消费者数量发生变化,所以触发了Rebalance机制。
所以我们在分析日志时可以看到,消费者是消费过一次数据的,并且消费后一段时间(kafka消费者的超时时间)触发了Rebalance机制,在之后,使用kafka cli命令查看消费者组详情的时候,就看不到对应的消费者了。

至此,kafka某一个topic消费不到数据的问题已经发现原因了。
原因找到了,至于解决方案就很多了:

  1. 调整超时时间
  2. 优化代码执行速度,或者改成线程池异步执行

因为我们的消费者代码很简单,只是调用apache atlas的api接口推送数据,但是因为未知原因,atlas接口调用比较慢,不能确定具体执行时长,所以我们选择了方案二。

按照解决方案修改代码后,部署测试,发现已经正常。

问题延伸

经过此次问题,延伸出一些kafka相关的知识需要巩固。

  1. kafka的Rebalance机制(为什么要有Rebalance机制,什么情况下会触发Rebalance机制)
  2. kafka消费的超时问题(session.timout.ms,heartbeat.interval.ms,max.poll.interval.ms三个参数)
  • 14
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kafka中,可以通过消费者程序来消费Topic中的消息,并打印出消息内容。如果你想打印出某个Topic消费消息,可以按照以下步骤进行: 1. 创建一个消费者程序,指定要消费Topic消费者组。 2. 在消费者程序中,实现消息消费的逻辑,并在消费消息的时候将消息内容打印出来。 3. 启动消费者程序,等待消息消费。 以下是一个简单的Java代码示例,用于消费一个名为“test_topic”的Topic,并将消息打印出来: ```java import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.KafkaConsumer; import java.util.Arrays; import java.util.Properties; public class ConsumerExample { public static void main(String[] args) { Properties props = new Properties(); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put(ConsumerConfig.GROUP_ID_CONFIG, "test_group"); props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props); consumer.subscribe(Arrays.asList("test_topic")); while (true) { ConsumerRecords<String, String> records = consumer.poll(100); for (ConsumerRecord<String, String> record : records) { System.out.printf("topic = %s, partition = %d, offset = %d, key = %s, value = %s%n", record.topic(), record.partition(), record.offset(), record.key(), record.value()); } } } } ``` 在上面的代码中,我们创建了一个消费者程序,并订阅了一个名为“test_topic”的Topic。在消费消息时,我们通过ConsumerRecord对象获取了消息的相关信息,包括Topic名称、分区ID、消息偏移量、消息Key和消息内容,并将其打印出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值