如何检查KafkaConsumer仍然分配了分区而没有使用poll()读取更多数据

时间:2017-09-28 14:46:18

标签: java apache-kafka kafka-consumer-api

在我的KafkaConsumer应用程序中,我想用poll()读取一批消息并处理它们。但处理可能会失败。在这种情况下,我想重试,直到我成功,但只有在消费者仍然拥有分区时才重试。我不想经常调用poll(),因为我不想阅读更多数据。

这是一段代码:

consumer = new KafkaConsumer<>(consumerConfig);
try {
    consumer.subscribe(config.topics() /** Callback does not work as I do not call poll in between */ );
    while (true) {
        ConsumerRecords<byte[], Value> values = consumer.poll(10000);
        while (/* I am still owner of partitions */) {
            try {
                process(values);
            } catch (Exception e) {
                log.error("I dont care, just retry while I own the partitions", e)
            }
        }
    }
} catch (WakeupException e) {
    // shutting down
} finally {
    consumer.close();
} 

3 个答案:

答案 0 :(得分:0)

有一种回调方法可以告诉您何时撤消您的消费者分区分配。除非您获得onPartitionRevoked()事件,否则请继续处理消息。

https://kafka.apache.org/0110/javadoc/org/apache/kafka/clients/consumer/ConsumerRebalanceListener.html#onPartitionsRevoked(java.util.Collection)

答案 1 :(得分:0)

答案 2 :(得分:0)

我得出的结论是,如果不使用当前的kafka consumer 10.2.x读取消息,就不可能调用poll()。但是,可以在处理失败后更新偏移。所以我更新了偏移量,好像消息从未被读过

while (!stopped) {
   ConsumerRecords<byte[], Value> values = consumer.poll(timeout);
    try {
        process(values);
    } catch (Exception e) {
        rewind(records);
        // Ensure a delay after errors to let dependencies recover
        Thread.sleep(delay);
    }
}

和倒带方法是

private void rewind(ConsumerRecords<byte[], Value> records) {
    records.partitions().forEach(partition -> {
        long offset = records.records(partition).get(0).offset();   
        consumer.seek(partition, offset);
    });
}

它解决了最初的问题