Kafka消费者同步和异步的JavaAPI代码演示

本文介绍了Kafka消费者的Java API,包括新版API的特点,如何设置从特定offset开始消费,以及自动和手动提交偏移量的方法。重点讲解了自动提交通过设置`enable.auto.commit`和`auto.commit.interval.ms`,以及手动提交的异步`commitAsync()`和同步`commitSync()`操作。在实际应用中,通常选择异步提交以提高性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

API文档
http://kafka.apache.org/10/javadoc/index.html?org/apache/kafka/clients/consumer/KafkaConsumer.html.

版本说明
消费者API也分为新版和旧版

开发中都是直接使用新版本API:
org.apache.kafka.clients.consumer.KafkaConsumer

注意:

1.旧版:有两个级别的API:

  • 低级/底层:可以手动维护offset

  • 高级/高层:自动维护offset

http://kafka.apache.org/0100/documentation.html#impl_consumer.

2.新版:直接将旧版的低阶和高阶整合了,不再区分,可以手动维护offset也可以自动维护offset。

从哪个offset开始消费

1.旧版API:offset保存在ZK中,通过参数指定

  • auto.offset.reset 的值为smallest:表示从分区的最小offset开始消费,类似与命令行消费时的 --from-beginning
  • auto.offset.reset 的值为largest:表示从分区的最大offset开始消费,也就是从最新的数据开始消费,类似命令行消费时的 不加–from-beginning

2.新版API:offset存储在默认主题__consumer_offsets中,通过参数指定

  • auto.offset.reset 的值为earliest :当各分区下有已提交的 Offset 时,从提交的 Offset开始消费;无提交的Offset 时,从最小/最早/最开始的数据开始消费;
  • auto.offset.reset 的值为latest : 当各分区下有已提交的 Offset 时,从提交的 Offset 开始消费;无提交的 Offset时,从最大/最新/最后的数据开始消费
  • auto.offset.reset 的值为none : Topic 各分区都存在已提交的 Offset 时,从 Offset 后开始消费;只要有一个分区不存在已提交的 Offset,则抛出异常。


如何提交偏移量

1.自动提交—一般都是用自动提交

  • enable.auto.commit设置为true 表示自动提交(老版本提交到ZK,新版本提交到默认主题__consumer_offsets中)
  • auto.commit.interval.ms设置一个自动提交offset的时间间隔

2.手动提交–对数据要求较高或想要精确控制时用手动提交!

  • enable.auto.commit设置为false表示需要手动提交偏移量

  • consumer.commitAsync();//异步提交

  • consumer.commitSync()//同步提交

导入Maven依赖

    <dependencies>
        <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka-clients</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka-streams</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- java编译插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

1.自动提交代码实现

  • 使用KafkaConsumer 自动提交偏移量时,需要在配置属性中将“enable.auto.commit”设置为true , 另外可以设置“auto.commit.interval.ms" 属性来控制自动提交的时间间隔。
  • Kafka 系统自动提交偏移量的底层实现调用了ConsumerCoordinator 的commitOffsetsSync()函数来进行同步提交,或者commitOffsetsAsync()函数来进行异步提交。自动提交的流程如图
    在这里插入图片描述
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;

import java.util.Arrays;
import java.util.Properties;

/**
 * 实现Kafka消费者自动提交偏移量
 * kafka-console-producer.sh --broker-list node1:9092 --topic test_topic
 */
public class MyKafkaConsumer_Auto {
    public static void main(String[] args) {
        //TODO 1.准备参数
        Properties props = new Properties();
        //指定kafka集群地址
        props.put("bootstrap.servers", "node1:9092,node2:9092,node3:9092");
        // key的反序列化类
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        // value的序列化类
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        //是否自动提交offset,true表示自动提交
        props.put("enable.auto.commit", "true");
        //自动确认提交偏移量offset的时间间隔
        props.put("auto.commit.interval.ms", "1000");
        //消费者组名称(如果不指定,会自动生成一个,但建议手动指定,方便管理)
        props.put("group.id", "test_offset_auto");
        //auto.offset.reset 的值更改为:earliest,latest,和none
        //1.earliest :当各分区下有已提交的 Offset 时,从提交的 Offset开始消费;无提交的Offset 时,从头开始消费;
        //2.latest : 当各分区下有已提交的 Offset 时,从提交的 Offset 开始消费;无提交的 Offset时,消费新产生的该分区下的数据
        //3.none : Topic 各分区都存在已提交的 Offset 时,从 Offset 后开始消费;只要有一个分区不存在已提交的 Offset,则抛出异常。
        props.put("auto.offset.reset", "latest");

        //TODO 2.创建kafka消费者对象consumer
        KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<String,String>(props);

        //TODO 3.订阅的topic
        kafkaConsumer.subscribe(Arrays.asList("order"));

        //TODO 4.开始消费
        while (true) {//消费者可以一直运行并且订阅主题消费其中的消息
            //poll表示Kafka获得消息
            //读取数据的延迟时间为100ms,每隔100ms去拉取数据
            //如果为0,立即拉取数据,如果没有数据返回为空
            //不能为负数
            ConsumerRecords<String, String> Records = kafkaConsumer.poll(100);
            for (ConsumerRecord<String, String> record : Records) {
                System.out.println("消费到的数据,分区:"+record.partition()+" offset:"+record.offset()+" value:" + record.value());
            }
        }
    }
}

2.手动提交代码实现
在编写消费者程序代码时,将配置属性“enable.auto.commit”的值设为“false”,则可以通过手动模式来提交偏移量。

Kafka Consumer 消费者程序类提供了两种手动提交偏移量的方式–同步提交commitSync()函数和异步提交commitAsync()函数。

同步提交和异步提交的区别在于:同步提交需要等待响应结果,会造成阻塞现象;异步提交不会被阻塞。

在实际应用场景中,会采用异步提交的方式来管理偏移量,这样有助于提升消费者程序的吞吐量。

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

/**
 * 实现Kafka消费者手动提交偏移量
 */

public class MyKafkaConsumer_ManualCommit {
    public static void main(String[] args) {
        //TODO 1.准备参数
        Properties props = new Properties();
        //kafka集群地址
        props.put("bootstrap.servers", "node1:9092");//node1:9092,node2:9092,node3:9092
        //消费者组名称(如果不指定,会自动生成一个,但一个都指定,方便管理)
        props.put("group.id", "myGroup");
        //是否自动提交offset,true表示自动提交,false表示使用手动提交
        //如果需要手动管理offset,一定要注意,这个配置要给false
        props.put("enable.auto.commit", "false");
        //自动提交偏移量时的时间间隔ms值,手动提交时不需要指定时间间隔
        //props.put("auto.commit.interval.ms", "1000");
        //配置offset重置位置
        //如果有offset记录就从记录的位置开始消费
        //如果没有记录offset,earliest表示从最开始的数据,latest表示从最新的数据,none报错
        props.put("auto.offset.reset", "earliest");

        //反序列化kv类型
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

        //TODO 2.创建Kafka消费者对象
        KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<>(props);

        //TODO 3.订阅主题
        kafkaConsumer.subscribe(Arrays.asList("order"));

        //TODO 4.开始消费
        //手动提交:
        //什么时候提交?
        //--1.指定时间间隔,每隔xxms提交一次,这就和自动提交一样了,还不如直接使用自动提交!
        //--2.每消费一条就提交一次!可以,但是可能会影响性能!
        //--3.每消费一小批就提交一次,如:每消费5条就提交一次!
        List<ConsumerRecord> list = new ArrayList<>();
        while (true){//消费者可以一直运行并订阅主题消费其中的消息!
            //poll表示从Kafka获得消息
            ConsumerRecords<String, String> Records = kafkaConsumer.poll(100);
            for (ConsumerRecord<String, String> record : Records) {
                System.out.println("消费到的数据,分区:" + record.partition() + " offset:" + record.offset() + " value:" + record.value());
                //kafkaConsumer.commitAsync();//每消费一条就提交一次
                list.add(record);
                if (list.size() >= 5) {
                    kafkaConsumer.commitSync();//每消费5条就提交一次!//同步
                    //kafkaConsumer.commitAsync();//每消费5条就提交一次!//异步
                    list.clear();
                    System.out.println("offset已提交");
                }
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值