Kafka 的客户端代码怎么写?

前言

本文隶属于专栏《1000个问题搞定大数据技术体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!

本专栏目录结构和参考文献请见1000个问题搞定大数据技术体系

正文

Producer 标准模范代码

package com.shockang.study.bigdata.kafka.clients;

import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.errors.RetriableException;

import java.util.Properties;

public class MyProducer {
    public static void main(String[] args) throws Exception {
        Properties props = new Properties();
        // 必须指定 集群的连接地址,最好多个地址
        props.put("bootstrap.servers", "localhost:9092");
        // 必须指定 Key 的序列化器
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        // 必须指定 value 的序列化器
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        // 在请求完成之前,Producer 要求 Leader 收到的确认数。这将控制发送的记录的持久性。
        props.put("acks", "-1");
        // 设置一个大于零的值将导致客户端重新发送其发送失败的任何记录
        props.put("retries", "3");
        // 每当多个记录被发送到同一分区时,生产者将尝试将记录批处理到一起,以减少请求。此配置控制以字节为单位的默认批处理大小。
        props.put("batch.size", "323840");
        // 一旦我们得到一个分区的batch.size值的记录,不管这个设置如何,它都会被立即发送,但是如果这个分区的累积字节数少于这个字节数,我们将“逗留”指定的时间,等待更多的记录出现
        props.put("linger.ms", "10");
        // Producer 可以用来缓冲等待发送到服务器的记录的总内存字节数
        props.put("buffer.memory", "33554432");
        // 此超时限制等待元数据获取和缓冲区分配的总时间
        props.put("max.block.ms", "3000");
        Producer<String, String> producer = new KafkaProducer<>(props);
        for (int i = 0; i < 100; i++) {
            // 推荐使用带 Callback 的 send 方法
            producer.send(new ProducerRecord<>("my-topic", Integer.toString(i), Integer.toString(i)), new Callback() {
                @Override
                public void onCompletion(RecordMetadata recordMetadata, Exception e) {
                    // 可以准确提示消息发送成功,发送失败可以通过 e 来针对处理
                    if (e == null) {
                        System.out.println("Send record succeed!");
                    } else {
                        System.out.println("Send record failed!");
                        if(e instanceof RetriableException){
                            // 处理可重试异常
                        }else{
                            // 处理不可重试异常
                        }
                    }
                }
            });
        }
        producer.close();
    }
}

Consumer 标准模范代码

package com.shockang.study.bigdata.kafka.clients;

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.PartitionInfo;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.errors.WakeupException;

import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class MyConsumer {
    public static void main(String[] args) {
        Properties props = new Properties();
        // 集群连接地址
        props.put("bootstrap.servers", "localhost:9092");
        // 如果Kafka中没有初始偏移量,或者服务器上不再存在当前偏移量(例如,因为该数据已被删除),该怎么办:earliest-自动将偏移量重置为最早偏移量
        props.put("auto.offset.reset", "earliest");
        // 如果为真,Consumer 的 offset 将定期在后台提交。
        props.put("enable.auto.commit", "false");
        // key 的反序列化器
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        // value 的反序列化器
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
        List<TopicPartition> partitions = new ArrayList<>();
        List<PartitionInfo> allPartitions = consumer.partitionsFor("my-topic");
        if (allPartitions != null && !allPartitions.isEmpty()) {
            for (PartitionInfo partitionInfo : allPartitions) {
                partitions.add(new TopicPartition(partitionInfo.topic(), partitionInfo.partition()));
            }
            consumer.assign(partitions);
        }
        try {
            for (; ; ) {
                // poll(long) 已经 deprecated,现在推荐使用  poll(Duration)
                ConsumerRecords<String, String> records = consumer.poll(Duration.of(Long.MAX_VALUE, ChronoUnit.MILLIS));
                for (ConsumerRecord<String, String> record : records) {
                    System.out.println(String.format("topic=%s,partition=%d,offset=%d", record.topic(), record.partition(), record.offset()));
                    // / 使用异步提交规避阻塞
                    consumer.commitAsync();
                }
            }
        } catch (WakeupException e) {
            e.printStackTrace();
        } finally {
            // 最后一次提交使用同步阻塞式提交
            consumer.commitSync();
            consumer.close();
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值