【Kafka】生产者和消费者API开发

一、生产者代码

生产者代码中主要通过KafkaProducer类生成生产者对象,传入Properties配置的参数。
注意send方法可以同步也可以异步,异步时需要实现Callback接口

package com.ptah.kafkaproducer;

import org.apache.kafka.clients.producer.Callback;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;

import java.util.Properties;

public class KafkaProducer01 {
    public static void main(String[] args) {
        //配置属性
        Properties props = new Properties();
        //kafka集群地址
        props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
        //acks代表消息确认机制   // 1 0 -1 all
        /**
         * acks = 0: 表示produce请求立即返回,不需要等待leader的任何确认。
         *          这种方案有最高的吞吐率,但是不保证消息是否真的发送成功。
         *
         * acks = 1: 表示leader副本必须应答此produce请求并写入消息到本地日志,之后produce请求被认为成功. 如果leader挂掉有数据丢失的风险

         * acks = -1或者all: 表示分区leader必须等待消息被成功写入到所有的ISR副本(同步副本)中才认为produce请求成功。
         *                  这种方案提供最高的消息持久性保证,但是理论上吞吐率也是最差的。
         */
        props.put("acks", "0");
        //重试的次数
        props.put("retries", 0);
        //缓冲区的大小  //默认32M
        props.put("buffer.memory", 33554432);
        //批处理数据的大小,每次写入多少数据到topic   //默认16KB
        props.put("batch.size", 16384);
        //可以延长多久发送数据   //默认为0 表示不等待 ,立即发送
        props.put("linger.ms", 1);
        //指定key和value的序列化器
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

        //创建producer对象
        KafkaProducer<String, String> producer = new KafkaProducer<String, String>(props);

        for(int i = 0; i < 200; i++){
            //向topic发送数据
            ProducerRecord<String, String> record = new ProducerRecord<String, String>("test", "key" + i, "value" + i);
            //(1)同步发送
            //producer.send(record);
            //(2)异步发送
            producer.send(record, new MyCallback(i, "value" + i));
        }

        //关闭producer
        producer.close();
    }
}

class MyCallback implements Callback {
    private final int key;
    private final String message;

    public MyCallback(int key, String message) {
        this.key = key;
        this.message = message;
    }

    @Override
    public void onCompletion(RecordMetadata metadata, Exception exception) {
        if(exception != null){
            System.out.println("报错");
        } else {
            System.out.println("成功");
        }

        if(metadata != null) {
            System.out.println("分区:"+metadata.partition());
            System.out.println("offset: "+metadata.offset());
        }
    }
}

二、消费者代码

通过KafkaConsumer类创建消费者对象,可以设置自动或者手动提交offset

1. 自动提交offset

package com.ptah.kafkaconsumer;

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

import java.time.Duration;
import java.util.Arrays;
import java.util.Properties;

public class KafkaConsumerAutoCommit {
    public static void main(String[] args) {
        Properties props = new Properties();
        //kafka集群地址
        props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
        //消费者组id
        props.put("group.id", "consumer-test");
        //自动提交偏移量
        props.put("enable.auto.commit", "true");
        //自动提交偏移量的时间间隔
        props.put("auto.commit.interval.ms", "1000");
        //默认是latest
        //earliest: 当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费
        //latest: 当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据
        //none : topic各分区都存在已提交的offset时,从offset后开始消费;只要有一个分区不存在已提交的offset,则抛出异常
        props.put("auto.offset.reset","earliest");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

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

        //设置topic
        consumer.subscribe(Arrays.asList("test"));

        //消费数据
        while(true){
            ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(1));
            for (ConsumerRecord<String, String> record : records) {
                //获取分区
                int partition = record.partition();
                //获取key
                String key = record.key();
                //获取offset
                long offset = record.offset();
                //获取topic
                String topic = record.topic();
                System.out.println("topic: " + topic + " 分区:" + partition + " key: " + key + " offset: " + offset);
            }
        }

    }
}

2. 手动提交offset

package com.ptah.kafkaconsumer;

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

import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Properties;

public class KafkaConsumerManulCommit {
    public static void main(String[] args) {
        Properties props = new Properties();
        //kafka集群地址
        props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
        //消费者组id
        props.put("group.id", "consumer-test");
        //自动提交偏移量
        props.put("enable.auto.commit", "false");
        //默认是latest
        //earliest: 当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费
        //latest: 当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据
        //none : topic各分区都存在已提交的offset时,从offset后开始消费;只要有一个分区不存在已提交的offset,则抛出异常
        props.put("auto.offset.reset","earliest");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

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

        //设置topic
        consumer.subscribe(Arrays.asList("test"));

        final int minBatchSize = 10;

        ArrayList<ConsumerRecord<String, String>> buffer = new ArrayList<ConsumerRecord<String, String>>();

        while (true) {
            ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(3));
            for (ConsumerRecord<String, String> record : records) {
                buffer.add(record);
            }
            if(buffer.size() >= minBatchSize){
                System.out.println("已处理条数:" + buffer.size());
                consumer.commitSync();
                buffer.clear();
            }
        }
    }
}

–The End–

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
手把手视频详细讲解项目开发全过程,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。 课程简介 细致简介了消息队列在大数据的应用场景、Kafka集群搭建、Kafka操作,基准测试、架构、编程、结合Kafka Eagle简介原理等 课程亮点 1,知识体系完备,从小白到大神各阶段读者均能学有所获。 2,生动形象,化繁为简,讲解通俗易懂。 3,结合工作实践及分析应用,培养解决实际问题的能力。 4,企业级方案设计,完全匹配工作场景。 适用人群 1、对大数据感兴趣的在校生及应届毕业生。 2、对目前职业有进一步提升要求,希望从事大数据行业高薪工作的在职人员。 3、对大数据行业感兴趣的相关人员。 课程内容 第一章 简介 1.1 消息队列简介 1.2 Kafka简介 1.3 Kafka的优势 1.4 哪些公司在使用Kafka 1.5 Kafka生态圈介绍 1.6 Kafka版本 第二章 环境搭建 2.1 搭建Kafka集群 2.2 目录结构分析 2.3 Kafka一键启动/关闭脚本 第三章 基础操作 3.1 创建topic 3.2 生产消息到Kafka 3.3 从Kafka消费消息 3.4 使用Kafka Tools操作Kafka 第四章 Kafka基准测试 第五章 Java编程操作Kafka 5.1 同步生产消息到Kafka中 5.2 从Kafka的topic中消费消息 5.3 异步使用带有回调函数方法生产消息 第六章 架构 6.1 Kafka重要概念 6.2 消费者组 第七章. Kafka生产者幂等性与事务 38 7.1 幂等性 第八章 分区和副本机制 8.1 生产者分区写入策略 8.2 消费者组Rebalance机制 8.3 消费者分区分配策略 8.4 副本机制 第九章 高级(High Level)API与低级(Low Level)API 9.1 高级API 9.2 低级API 9.3 手动消费分区数据 第十章 监控工具Kafka-eagle介绍 10.1 Kafka-Eagle简介 10.2 安装Kafka-Eagle 10.3 Kafka度量指标 第十一章 Kafka原理 11.1 分区的leader与follower 11.2 Kafka生产、消费数据工作流程 11.3 Kafka的数据存储形式 11.4 消息不丢失机制 11.5 数据积压 第十二章 Kafka中数据清理(Log Deletion) 12.1 日志删除 12.2 日志压缩(Log Compaction)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值