将确认传递给Spring KafkaListener消费者方法

时间:2020-01-14 19:23:31

标签: java spring-kafka

我正在尝试在kafka中关闭自动提交,而是手动进行。为此,我在application.properties中设置了spring.kafka.properties.enable.auto.commit=false

我目前也有一个带有以下标头的方法:

@KafkaListener(id="${"+ KafkaConfiguration.APP_REQUEST_ID +"}", topics = "${"+KafkaConfiguration.PPA_REQUEST_TOPIC +"}")
public void receive(@Payload String message,
                    @Headers MessageHeaders headers)

我的理解是,为了手动提交,我需要访问Acknowledgement对象,该对象将作为参数传递给我的receive()方法。我的问题:如果我将标题更改为

@KafkaListener(id="${"+ KafkaConfiguration.APP_REQUEST_ID +"}", topics = "${"+KafkaConfiguration.APP_REQUEST_TOPIC +"}")
public void receive(@Payload String message,
                    @Headers MessageHeaders headers,
                    Acknowledgment acknowledgment)

Acknowledgment是否会自动传递,还是我需要进行其他更改?

2 个答案:

答案 0 :(得分:1)

是的,这样会将Acknowledgment实例传递到您的侦听器方法中。成功处理收到的消息后,您应该致电acknowledgement.acknowledge();(仅在您要手动确认时才需要)

我还将切换到MANUAL ackmode并关闭自动提交(您已经完成的操作),例如通过提供自定义的Spring Boot配置类-也可以通过application.properties进行配置:

@Configuration
class KafkaConfiguration {

        @Bean
        ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory(KafkaProperties kafkaProperties) {

            final Map<String, Object> consumerProperties = kafkaProperties.buildConsumerProperties();
            consumerProperties.put(ENABLE_AUTO_COMMIT_CONFIG, false);

            ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
            factory.getContainerProperties().setAckMode(MANUAL);

            return factory;
        }
    }
}

如果您不想手动确认,则使用另一个ackmode可能更方便且更合适:

https://docs.spring.io/spring-kafka/api/org/springframework/kafka/listener/ContainerProperties.AckMode.html

AckMode.RECORD很舒服,因为如果侦听器的方法实现成功完成(不会引发异常),传递给侦听器方法的Kafka记录将被自动确认。

答案 1 :(得分:1)

简短的回答,您无需传递Acknowledgment,它是收到的消息的一部分。

按照documentation

使用手动 AckMode 时,您还可以向监听者提供 Acknowledgment 。以下示例还显示了如何使用其他容器工厂。

@KafkaListener(id = "cat", topics = "myTopic",
          containerFactory = "kafkaManualAckListenerContainerFactory")
public void listen(String data, Acknowledgment ack) {
    ...
    ack.acknowledge();
}

摘自@KafkaListener文档:

允许带批注的方法具有类似于MessageMapping提供的灵活签名,即

  • ConsumerRecord以访问原始Kafka消息
  • 确认手动确认
  • @Payload注释的方法参数,包括对验证的支持
  • @Header注释的方法参数以提取由KafkaHeaders定义的特定标头值
  • @Headers注释的参数,也必须可以将其分配给Map才能访问所有标题。
  • MessageHeaders自变量,用于访问所有标头。
  • MessageHeaderAccessor,可方便地访问所有方法参数。