Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 卡夫卡向我发送已处理的消息_Java_Apache Kafka_Listener_Consumer - Fatal编程技术网

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

我有一个从Kafka读取消息的Java服务。服务很简单。我有一个听众:

@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");