Java 卡夫卡向我发送已处理的消息
我有一个从Kafka读取消息的Java服务。服务很简单。我有一个听众:Java 卡夫卡向我发送已处理的消息,java,apache-kafka,listener,consumer,Java,Apache Kafka,Listener,Consumer,我有一个从Kafka读取消息的Java服务。服务很简单。我有一个听众: @KafkaListener(topics = "${kafka.topic.name}", groupId = "${kafka.topic.group}", containerFactory = "mesagueKafkaListenerContainerFactory") 那么,我有这个配置: @Autowired private KafkaProperty kafkaProperty; private
@KafkaListener(topics = "${kafka.topic.name}", groupId = "${kafka.topic.group}", containerFactory = "mesagueKafkaListenerContainerFactory")
那么,我有这个配置:
@Autowired
private KafkaProperty kafkaProperty;
private ConsumerFactory<String, KafkaMessage> mesagueConsumerFactory() {
Map<String, Object> props = new HashMap<>();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, this.kafkaProperty.getServers());
props.put(ConsumerConfig.GROUP_ID_CONFIG, this.kafkaProperty.getGroupIdTest());
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, this.kafkaProperty.getAutoCommit());
return new DefaultKafkaConsumerFactory<>(props, new StringDeserializer(),
new JsonDeserializer<>(KafkaMessage.class));
}
private ConsumerFactory<String, String> consumerFactory(String groupId) {
Map<String, Object> props = new HashMap<>();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, this.kafkaProperty.getServers());
props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, this.kafkaProperty.getAutoCommit());
return new DefaultKafkaConsumerFactory(props, new StringDeserializer(), new JsonDeserializer<>(KafkaMessage.class));
}
@Bean
public ConcurrentKafkaListenerContainerFactory<String, KafkaMessage> mesagueKafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, KafkaMessage> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(mesagueConsumerFactory());
factory.getContainerProperties().setAckMode(AckMode.MANUAL_IMMEDIATE);
factory.getContainerProperties().setErrorHandler(new KafkaErrorHandler());
return factory;
}
当我向队列发送消息时,服务会处理它
但当我重新启动服务时,它会再次读取队列中的所有消息(消息也已处理)
我只想处理未处理的新邮件
提前感谢。您正在将
自动提交设置为false,而不是手动提交偏移。这意味着消费者不会告诉卡夫卡“嘿,我已经用完了这些信息”。因此,下次重新启动使用者时,它将从上次提交的消息开始,在您的情况下,这可能是主题中的第一条消息。如果要将auto.commit保持为false,则需要在收到新消息时确认
@KafkaListener(....)
public void consume(ConsumerRecord<?, ?> consumerRecord,
Acknowledgment acknowledgment) {
// Consume record
acknowledgment.acknowledge();
}
@KafkaListener(…)
公共无效消费(消费记录消费记录,
致谢(致谢){
//消费记录
确认。确认();
}
自动提交应为true
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "true");
并将其添加到属性中,以便它始终处理未处理的数据
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
如果“自动提交”为false,则必须手动提交。如果不手动执行,偏移量将永远不会增加,重新启动后您将一次又一次地获得相同的数据。我理解(可能是错误的)->AckMode.MANUAL\u IMMEDIATE处理提交本身。来自Spring Kafka文档:“MANUAL\u IMMEDIATE:在确认后立即提交偏移量。acknowledge()方法由侦听器调用。“源:
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");