Kafka-Java客户端消费者的实现

133 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情

大家好,我是尚影嫣🌷,一名Java后端程序媛。如果您喜欢我的文章,欢迎点赞➕关注❤️,让我们一起成为更好的我们~

1.消费者的基本实现

package com.yanf.kafka;

import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;

import java.time.Duration; 123456789

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

public class MySimpleConsumerDemo {
    private final static String TOPIC_NAME = "my-replicated-topic";
    private final static String CONSUMER_GROUP_NAME = "testGroup";

    public static void main(String[] args) {
        Properties props = new Properties();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,
                "172.16.253.38:9092,172.16.253.38:9093,172.16.253.38:9094");
        // 消费分组名
        props.put(ConsumerConfig.GROUP_ID_CONFIG, CONSUMER_GROUP_NAME);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,
                StringDeserializer.class.getName());
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,
                StringDeserializer.class.getName());
        //1.创建⼀个消费者的客户端
        KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(props);
        //2. 消费者订阅主题列表
        consumer.subscribe(Arrays.asList(TOPIC_NAME));
        while (true) {
            /*
             * 3.poll() API 是拉取消息的⻓轮询
             */
            ConsumerRecords<String, String> records =
                    consumer.poll(Duration.ofMillis(1000));
            for (ConsumerRecord<String, String> record : records) {
                //4.打印消息
                System.out.printf("收到消息:partition = %d,offset = %d, key =
                        % s, value = % s % n ", record.partition(),
                record.offset(), record.key(), record.value());
            }
        }
    }
}

2.关于消费者自动提交和手动提交offset

1)提交的内容

消费者无论是自动提交还是手动提交,都需要将所属的消费组、消费的某个主题、消费的某个分区及消费的偏移量信息,提交到集群的_consumer_offsets主题里。

2)自动提交

消费者poll消息下来后就会提交offset。

注意:自动提交会丢消息。因为消费者在消费前提交offset,有可能会有提交完尚未消费时,消费者挂了的情况。

3)手动提交

需要将自动提交的配置改成false。

  • 手动同步提交

在消费完消息后调用同步提交的方法,当集群返回ack前⼀直阻塞,返回ack后表示提交成功,执行之后的逻辑

while (true) {

        /*
         * poll() API 是拉取消息的⻓轮询
         */
        ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000));

        for (ConsumerRecord<String, String> record : records) {
            System.out.printf("收到消息:partition = %d,offset = %d, key = %s, value = %s%n", record.partition(), record.offset(), record.key(), record.value());
        }

        //所有的消息已消费完
        if (records.count() > 0) {//有消息
            // 手动同步提交offset,当前线程会阻塞,直到offset提交成功
            // ⼀般使用同步提交,因为提交之后⼀般也没有什么逻辑代码了
            consumer.commitSync();//=======阻塞=== 提交成功

        }
    }
}