春季卡夫卡消费者不尊重自动偏移量重置=最新

时间:2019-12-21 18:22:10

标签: java spring-boot apache-kafka spring-kafka

我们有1个Kafka主题和1个分区:

从spring boot kafka消费者那里看到了一个相当奇怪的行为。春季kafka使用者始终从重新启动主题开始就进行消费。  我已经按如下方式配置了Spring Kafka监听器

kafka监听器:

@KafkaListener(topics = "${application.kafkaInputTopic}", groupId = "${spring.kafka.consumer.group-id}")
public void listen(String message) {
    log.debug("SG message received. Parsing...");
    TransmissionMessage transmissionMessage;
    SGTransmission transmission = parseMessage(message);
    //Porcess Transmission......
}

消费者配置和春季消费者容器自动装配豆

@Resource
public Environment env;

@Bean
KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() {
    ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory();
    factory.setConsumerFactory(consumerFactory());
   // I know this isnt right, should be run in 1 thread as there isonly 
   //partition in the topic
    factory.setConcurrency(10);
    factory.getContainerProperties().setPollTimeout(3000);

    factory.getContainerProperties().setAckMode(AbstractMessageListenerContainer.AckMode.MANUAL);

    factory.getContainerProperties().setSyncCommits(true);
    return factory;
}

@Bean
public ConsumerFactory<String, String> consumerFactory() {
    return new DefaultKafkaConsumerFactory<>(consumerConfigs());
}

@Bean
public Map<String, Object> consumerConfigs() {
    Map<String, Object> propsMap = new HashMap();
    propsMap.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, env.getProperty(Constants.SPRING_KAFKA_SECURITY_PROTOCOL));
    propsMap.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, env.getProperty(Constants.SPRING_KAFKA_BOOTSTRAP_SERVERS));
    propsMap.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    propsMap.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);

    propsMap.put(ConsumerConfig.GROUP_ID_CONFIG, env.getProperty(Constants.SPRING_KAFKA_GROUP_ID));
    return propsMap;
}

spring application yaml

kafka:
    bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVERS}
    properties:
    consumer:
        # If this consumer does not have an offset yet, start at latest offset.
        # Be careful with `earliest`, this will use the first (available) offset in the topic, which is most likely not what you want.
        auto-offset-reset: latest
        group-id: ${KAFKA_GROUP_ID}

每次使用者崩溃并重新启动时,都会从头开始读取所有消息。就像在application.yaml

中看到的那样
  

自动偏移重置:最新

我可能会忽略经纪人端或使用者端的一些其他配置,这导致使用者每次重新启动时都要从头开始读取吗?

1 个答案:

答案 0 :(得分:1)

您可能必须以某种方式提交了初始偏移量,也许是在完成此配置之前。

  

factory.getContainerProperties()。setAckMode(AbstractMessageListenerContainer.AckMode.MANUAL);

这意味着您有责任提交偏移量。

使用AckMode.BATCH(默认设置)或AckMode.RECORD

或者,使用kafka-consumer-groups CLI工具删除当前提交的偏移量(您也可以使用同一工具列出当前偏移量)。

或使用该组的UUID每次获取一个新组。

编辑

您还可以让您的监听器类实现ConsumerSeekAware,并在callback.seekToEnd(partitions)中调用onPartitionsAssigned()