消费者消费消息时会根据之前提交的消费位移offset去kafka拉取offset之后的消息进行消费。但是一些情况下消费者开始消费时会没有消费位移,比如一个新的消费组建立的时候,或者消费组内的一个新的消费者订阅了一个新的主题,或者__consumer_offsets主题中关于这个消费组的位移信息已经过期而被删除的时候。这时消费者开始消费的消费位移就由客户端参数auto.offset.reset来决定,这个参数默认值为"latest",表示从分区末尾开始消费消息。也可以改为"earliest",表示从起始处来消费消息。也可以配置为“none”,表示找不到消费位移时直接抛出NoOffsetForPartitionException异常。
除了上述的位移重置的配置参数,消费者也可以通过seek()方法手动重置位移,此处需要注意的一个点在于consumer在通过poll方法拉取消息时,poll方法会通过调用fetcher.fetchedRecords()方法去获取消费者订阅的分区,只有这个方法返回时才能通过以下方式去获取topicPartition并且通过seek()方法重置位移。
Set<TopicPartition> topicPartition= consumer.assignment();
topicPartition.forEach(topicPartition1 -> consumer.seek(topicPartition1,offset));
poll方法带有Duration参数,可能会存在到达指定时间后,poll()方法直接返回,内部的分区分配逻辑还未实施,那么此时获取到的consumer.assignment()就是一个空集合,所以调用时需注意进行循环判断调用poll获取订阅的分区后再去调用seek方法重置位移。
消费者内的seek方法有如下几种: