Kafka代码实现--from-beginning,读取历史未消费的数据

Kafka实际环境有可能会出现Consumer全部宕机,虽然基于Kafka的高可用特性,消费者群组中的消费者可以实现再均衡,所有Consumer不处理数据的情况很少,但是还是有可能会出现,此时就要求Consumer重启的时候能够读取在宕机期间Producer发送的数据。基于消费者订阅模式默认是无法实现的,因为只能订阅最新发送的数据。

通过消费者命令行可以实现,只要在命令行中加上--from-beginning即可(具体可见文章 Kafka安装与配置 ),但是通过Java客户端代码如何实现呢?这就要用到消息偏移量的重定位方法 seek() 或者直接使用 seekToBeginning() 方法,基于再均衡监听器,在给消费者分配分区的时候将消息偏移量跳转到起始位置 。

代码示例如下:

public class Consumer {
    private static final String server = "192.168.3.22:9092";

    public static void main(String[] args) {
        Properties properties = new Properties();
        properties.put("bootstrap.servers", server);
        properties.put("group.id", "kafka.group.user");

        KafkaConsumer consumer = new KafkaConsumer(properties, new StringDeserializer(), new StringDeserializer());
        consumer.subscribe(Collections.singletonList("kafka.topic.user"), new ConsumerRebalanceListener() {
            @Override
            public void onPartitionsRevoked(Collection collection) {

            }

            @Override
            public void onPartitionsAssigned(Collection collection) {
                Map beginningOffset = consumer.beginningOffsets(collection);

                //读取历史数据 --from-beginning
                for(Map.Entry entry : beginningOffset.entrySet()){
                    // 基于seek方法
                    //TopicPartition tp = entry.getKey();
                    //long offset = entry.getValue();
                    //consumer.seek(tp,offset);

                    // 基于seekToBeginning方法
                    consumer.seekToBeginning(collection);
                }
            }
        });

        try {
            while (true) {
                ConsumerRecords records = consumer.poll(100);
                for (ConsumerRecord record : records) {
                    System.out.println("partition:" + record.partition() + ",key:" + record.key() + ",value:" + record.value());
                    consumer.commitAsync();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                consumer.commitSync();
            } finally {
                consumer.close();
            }
        }
    }
}

你可能感兴趣的:(消息中间件)