Java 如何在Spring Kafka客户端中查找偏移量?

Java 如何在Spring Kafka客户端中查找偏移量?,java,apache-kafka,kafka-consumer-api,spring-kafka,Java,Apache Kafka,Kafka Consumer Api,Spring Kafka,在开发提要中的微服务消费数据时,我们使用了ConsumerSekAware和SeekToBegining。当我们准备好时,我们希望消费者使用补偿。由于文档的原因,我无法真正理解seekToEnd代表什么。这是否意味着,它将搜索到偏移量(最后确认的消息)还是将搜索到主题的最后一条消息(无论偏移量如何),并等待新消息 @Slf4j public class KafkaSeekOffsetAwareListener implements ConsumerSeekAware { protecte

在开发提要中的微服务消费数据时,我们使用了
ConsumerSekAware
SeekToBegining
。当我们准备好时,我们希望消费者使用补偿。由于文档的原因,我无法真正理解
seekToEnd
代表什么。这是否意味着,它将搜索到偏移量(最后确认的消息)还是将搜索到主题的最后一条消息(无论偏移量如何),并等待新消息

@Slf4j
public class KafkaSeekOffsetAwareListener implements ConsumerSeekAware {
    protected final ThreadLocal<ConsumerSeekCallback> seekCallBack = new ThreadLocal<>();

    @Override
    public void registerSeekCallback(ConsumerSeekCallback callback) {
        log.info("Registering seek callback");
        this.seekCallBack.set(callback);
    }

    @Override
    public void onPartitionsAssigned(Map<TopicPartition, Long> assignments, ConsumerSeekCallback callback) {
        log.info("Incoming Topic Partitions {}", assignments);
---->   assignments.forEach((assignment, assignmentKey) -> assignments.forEach((t, o) -> callback.seekToBeginning(t.topic(), t.partition())));
    }

    public void onIdleContainer(Map<TopicPartition, Long> assignments, ConsumerSeekCallback callback) {
        log.info("Container idle");
    }
}
@Slf4j
公共类KafkaseekOffsetWareListener实现ConsumerSekAware{
受保护的最终ThreadLocal seekCallBack=新ThreadLocal();
@凌驾
公共无效注册表seekCallback(ConsumerSekCallback回调){
log.info(“注册查找回调”);
this.seekCallBack.set(回调);
}
@凌驾
已签名分区上的公共void(映射分配、ConsumerSekCallback){
info(“传入主题分区{}”,赋值);
---->assignments.forEach((assignment,assignmentKey)->assignments.forEach((t,o)->callback.seektobegining(t.topic(),t.partition());
}
public void onIdleContainer(映射分配、ConsumerSekCallback回调){
log.info(“容器空闲”);
}
}
由于文档的原因,我无法真正理解seekToEnd代表什么。这是否意味着,它将搜索到偏移量(最后确认的消息)还是将搜索到主题的最后一条消息(无论偏移量如何),并等待新消息

@Slf4j
public class KafkaSeekOffsetAwareListener implements ConsumerSeekAware {
    protected final ThreadLocal<ConsumerSeekCallback> seekCallBack = new ThreadLocal<>();

    @Override
    public void registerSeekCallback(ConsumerSeekCallback callback) {
        log.info("Registering seek callback");
        this.seekCallBack.set(callback);
    }

    @Override
    public void onPartitionsAssigned(Map<TopicPartition, Long> assignments, ConsumerSeekCallback callback) {
        log.info("Incoming Topic Partitions {}", assignments);
---->   assignments.forEach((assignment, assignmentKey) -> assignments.forEach((t, o) -> callback.seekToBeginning(t.topic(), t.partition())));
    }

    public void onIdleContainer(Map<TopicPartition, Long> assignments, ConsumerSeekCallback callback) {
        log.info("Container idle");
    }
}

这是一回事。主题中的最后一个偏移量是最后一个确认的偏移量(假设生产者甚至启用了acks},并且无论偏移量是多少,查找到末尾都会将消耗的“光标”移动到末尾;将位置设置到分区的末尾,而不管该消耗者的“当前”位置;下一个接收到的记录将是执行查找后添加到分区的下一个记录

将跳过消费者停止时发布的任何记录。

请参阅JavaDocs:

/**
 * Seek to the last offset for each of the given partitions. This function evaluates lazily, seeking to the
 * final offset in all partitions only when {@link #poll(Duration)} or {@link #position(TopicPartition)} are called.
 * If no partitions are provided, seek to the final offset for all of the currently assigned partitions.
 * <p>
 * If {@code isolation.level=read_committed}, the end offset will be the Last Stable Offset, i.e., the offset
 * of the first message with an open transaction.
 *
 * @throws IllegalArgumentException if {@code partitions} is {@code null}
 * @throws IllegalStateException if any of the provided partitions are not currently assigned to this consumer
 */
@Override
public void seekToEnd(Collection<TopicPartition> partitions) {
/**
*查找每个给定分区的最后一个偏移量。此函数的计算是惰性的,查找
*仅当调用{@link#poll(Duration)}或{@link#position(TopicPartition)}时,所有分区中的最终偏移量。
*如果没有提供分区,则查找当前分配的所有分区的最终偏移量。
*
*如果{@code isolation.level=read_committed},则结束偏移量将是最后一个稳定的偏移量,即偏移量
*具有打开事务的第一条消息的。
*
*如果{@code partitions}为{@code null},则@throws IllegalArgumentException
*@如果提供的任何分区当前未分配给此使用者,则会引发IllegalStateException
*/
@凌驾
公共void seekToEnd(集合分区){

正如您所看到的,这是一个纯粹的Apache Kafka客户端。Spring for Apache Kafka只不过是对该功能的授权。我甚至会说,说Spring for Apache Kafka是一个“Kafka客户端”是错误的。它只是围绕标准Apache Kafka客户端的一个包装器和高级Spring API。

您尝试过使用该方法吗?据我所知,它似乎将使用写入主题的最新消息。