spring.kafka.consumer.auto-offset-reset如何在spring-kafka

时间:2017-10-16 08:03:20

标签: java spring apache-kafka kafka-producer-api spring-kafka

KafkaProperties java doc:

/**
  * What to do when there is no initial offset in Kafka or if the current offset
  * does not exist any more on the server.
  */
private String autoOffsetReset;

我有一个包含application.properties

的hello world appllication
spring.kafka.consumer.group-id=foo
spring.kafka.consumer.auto-offset-reset=latest

在这种情况下,将为所有条目调用@KafkaListener方法。但是预期的结果是仅针对我发送的最新3个选项调用@KafkaListener方法。我尝试使用其他选项:

spring.kafka.consumer.auto-offset-reset=earlisest

但行为相同。

你能解释一下吗?

P.S。

代码示例:

@SpringBootApplication
public class Application implements CommandLineRunner {

    public static Logger logger = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args).close();
    }

    @Autowired
    private KafkaTemplate<String, String> template;

    private final CountDownLatch latch = new CountDownLatch(3);

    @Override
    public void run(String... args) throws Exception {
        this.template.send("spring_kafka_topic", "foo1");
        this.template.send("spring_kafka_topic", "foo2");
        this.template.send("spring_kafka_topic", "foo3");
        latch.await(60, TimeUnit.SECONDS);
        logger.info("All received");
    }

    @KafkaListener(topics = "spring_kafka_topic")
    public void listen(ConsumerRecord<?, ?> cr) throws Exception {
        logger.info(cr.toString());
        latch.countDown();
    }
}

更新

Behasviour并不依赖于 spring.kafka.consumer.auto-offset-reset

它仅取决于spring.kafka.consumer.auto-offset-reset = earliest

spring.kafka.consumer.enable-auto-commit

如果我设置spring.kafka.consumer.enable-auto-commit=false - 我会看到所有记录。

如果我设置spring.kafka.consumer.enable-auto-commit=true - 我只看到3个最后的记录。

请澄清spring.kafka.consumer.auto-offset-reset财产的消息

1 个答案:

答案 0 :(得分:0)

Spring Boot中的KafkaProperties执行此操作:

public Map<String, Object> buildProperties() {
        Map<String, Object> properties = new HashMap<String, Object>();
        if (this.autoCommitInterval != null) {
            properties.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG,
                    this.autoCommitInterval);
        }
        if (this.autoOffsetReset != null) {
            properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,
                    this.autoOffsetReset);
        }

buildProperties()来自buildConsumerProperties(),后者依次为:

@Bean
@ConditionalOnMissingBean(ConsumerFactory.class)
public ConsumerFactory<?, ?> kafkaConsumerFactory() {
    return new DefaultKafkaConsumerFactory<Object, Object>(
            this.properties.buildConsumerProperties());
}

因此,如果您使用自己的ConsumerFactory bean定义,请确保重用KafkaPropertieshttps://docs.spring.io/spring-boot/docs/1.5.7.RELEASE/reference/htmlsingle/#boot-features-kafka-extra-props

<强>更新

行。我知道发生了什么。

尝试添加此属性:

spring.kafka.consumer.enable-auto-commit=false

这样我们就不会根据一些提交间隔进行异步自动提交。

我们的应用程序中的逻辑基于latch.await(60, TimeUnit.SECONDS);之后的退出事实。当我们得到3预期记录时,我们退出。这样,来自消费者的异步自动提交可能还没有发生。因此,下次运行应用程序时,使用者会从未提交的偏移量中轮询数据。

当我们关闭自动提交时,我们有一个AckMode.BATCH,它是同步执行的,我们有能力在这个foo消费者群体的主题中看到真正最新的重新记录。