我是Kafka的新手,并使用Spring boot @kafkalistener创建了消费者。
我的用例是一旦从kafka分区读取消息,我需要处理,当出现任何异常时,需要在一段时间后重新处理消息。在异常情况下,我不应该更新偏移量,在服务器启动后,我需要再次处理消息。
以下是配置
@Configuration
@EnableKafka
public class ReceiverConfiguration {
@Bean
KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory();
factory.setConsumerFactory(consumerFactory());
factory.setConcurrency(10);
factory.getContainerProperties().setPollTimeout(3000);
factory.getContainerProperties().setAckMode(AckMode.MANUAL);
factory.getContainerProperties().setSyncCommits(true);
return factory;
}
@Bean
public ConsumerFactory<String, String> consumerFactory() {
return new DefaultKafkaConsumerFactory<String, String>(consumerConfigs());
}
@Bean
public Map<String, Object> consumerConfigs() {
Map<String, Object> propsMap = new HashMap();
propsMap.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "<some broker configuration>");
propsMap.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
propsMap.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "6000");
propsMap.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
propsMap.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, CustomDeserializer.class);
propsMap.put(ConsumerConfig.GROUP_ID_CONFIG, "Test-Consumer-Group");
propsMap.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
return propsMap;
}
@Bean
public Listener listener() {
System.out.println("%%%%%%%%% Initializing Listener %%%%%%%");
return new Listener();
}
}
以下是监听器类
public class Listener {
private static final Logger logger = LoggerFactory.getLogger(Listener.class);
public CountDownLatch getCountDownLatch1() {
return countDownLatch1;
}
private CountDownLatch countDownLatch1 = new CountDownLatch(1);
@KafkaListener(topics = "topic")
public void listen(ConsumerRecord<String, CustomObject> record, Acknowledgment ack) throws Exception{
logger.info("******** 1 message: "+record);
//ack.acknowledge();
}
}
方案1:在消费者服务运行期间,当生产者发送消息时,监听器类读取消息而不更新偏移量,直到这部分看起来不错。如果我停止使用者,则会在使用者组中更新偏移量。 问题:在服务器停止方案期间不应更新偏移量。一旦我的后端处理问题得到解决,当我重新启动我的消费者服务时,我只需要在未提交偏移量时再次使用该消息。但是这里提交了offset,我没有机会再次从分区中获取消息。
方案2:假设我的消费者服务已关闭,生产者向Topic分区发送消息,可以看到偏移量没有增加且滞后为1.仍然使用ack.acknowledge()启用服务,即代码仅被注释掉,即使在消费者群体中提交了偏移量。 问题:直到我确认偏移量,不应该提交偏移量。服务器启动时注意到的问题。
请帮我解决问题,无法找到正确的重定向。
感谢您的帮助