精选干货 在java中创建kafka
这个详细的教程将帮助你创建一个简单的Kafka生产者,该生产者可将记录发布到Kafka集群。
通过优锐课的java学习架构分享中,在本教程中,我们将创建一个简单的Java示例,该示例创建一个Kafka生产者。 你创建一个名为my-example-topic的新复制的Kafka主题,然后创建一个使用该主题发送记录的Kafka生产者。将向Kafka制作人发送记录。同步发送记录,稍后,你将异步发送记录。
在你开始前
本教程的前提条件是命令行中的Kafka以及Kafka群集和故障转移基础知识。
本教程是系列教程的一部分。 如果不确定什么是卡夫卡,则应从什么开始。 如果你不熟悉Kafka的体系结构,那么建议你阅读Kafka Architecture,Kafka Topics Architecture,Kafka Producer Architecture和Kafka Consumer Architecture。
创建复制的Kafka主题
#!/usr/bin/env bash cd ~/kafka-training ## Create topics kafka/bin/kafka-topics.sh --create \ --replication-factor 3 \ --partitions 13 \ --topic my-example-topic \ --zookeeper localhost:2181 ## List created topics kafka/bin/kafka-topics.sh --list \ --zookeeper localhost:2181
在上面,我们创建了一个名为my-example-topic的主题,具有13个分区和3的复制因子。然后列出了Kafka主题。
如下运行create-topic.sh。
运行create-topic.sh的输出
~/kafka-training/lab3 $ ./create-topic.sh Created topic "my-example-topic". __consumer_offsets my-example-topic my-failsafe-topic
Gradle构建脚本
在此示例中,我们使用gradle构建项目。
〜/ kafka-training / lab3 / solution / build.gradle group 'cloudurable-kafka' version '1.0-SNAPSHOT' apply plugin: 'java' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile 'org.apache.kafka:kafka-clients:0.10.2.0' compile 'ch.qos.logback:logback-classic:1.2.2' }
请注意,我们导入了jar文件kafka-clients:0.10.2.0。 Apache Kafka使用sl4j,因此要设置日志记录,我们使用logback(ch.qos.logback:logback-classic:1.2.2)。
构造一个 Kafka 生产者Construct a Kafka
要创建Kafka生产者,你需要向其传递引导服务器列表(Kafka代理列表)。 你还将指定一个client.id来唯一标识此Producer客户端。 在此示例中,我们将发送带有ID的消息。 邮件正文是一个字符串,因此我们需要一个记录值序列化程序,因为我们将在Kafka的“记录值”字段中发送邮件正文。 消息ID(长)将作为Kafka的记录密钥发送。 你将需要指定一个密钥序列化程序和一个值序列化程序,Kafka将使用它们来将消息ID编码为Kafka记录键,并将消息主体编码为Kafka记录值。
常见的Kafka导入和常量
接下来,我们将导入Kafka软件包,并为该主题定义一个常量,并定义一个常量,以定义生产者将连接的引导服务器列表。
KafkaProducerExample.java-导入和常量:
〜/ kafka-training / lab3 / src / main / java / com / cloudurable / kafka / KafkaProducerExample.java package com.cloudurable.kafka; import org.apache.kafka.clients.producer.*; import org.apache.kafka.common.serialization.LongSerializer; import org.apache.kafka.common.serialization.StringSerializer; import java.util.Properties; public class KafkaProducerExample { private final static String TOPIC = "my-example-topic"; private final static String BOOTSTRAP_SERVERS = "localhost:9092,localhost:9093,localhost:9094";
请注意,KafkaProducerExample导入配置为Kafka记录键序列化程序的LongSerializer,并导入配置为记录值序列化程序的StringSerializer。 常量BOOTSTRAP_SERVERS设置为localhost:9092,localhost:9093,localhost:9094,这是我们在上一课中启动的三台Kafka服务器。 继续并确保所有三台Kafka服务器都在运行。 常量TOPIC设置为我们刚刚创建的复制的Kafka主题。
创建Kafka生产者以发送记录
现在,我们导入了Kafka类并定义了一些常量,让我们创建一个Kafka生产者。
KafkaProducerExample.java-创建生产者以发送记录
〜/ kafka-training / lab3 / src / main / java / com / cloudurable / kafka / KafkaProducerExample.java public class KafkaProducerExample { ... private static Producer<Long, String> createProducer() { Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS); props.put(ProducerConfig.CLIENT_ID_CONFIG, "KafkaExampleProducer"); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); return new KafkaProducer<>(props); }
要创建Kafka生产者,你可以使用java.util.Properties并定义某些属性,这些属性我们将传递给KafkaProducer的构造函数。
上面的KafkaProducerExample.createProducer将BOOTSTRAP_SERVERS_CONFIG(“ bootstrap.servers)”属性设置为我们前面定义的代理地址列表。 BOOTSTRAP_SERVERS_CONFIG值是主机/端口对的逗号分隔列表,生产者用于建立与Kafka集群的初始连接。 无论我们在此处列出哪些服务器,生产者都将使用群集中所有服务器。 该列表仅指定用于发现Kafka集群的全套服务器的初始Kafka代理。 如果此列表中的服务器已关闭,则生产者将仅转到该列表中的下一个代理,以发现Kafka群集的完整拓扑。
CLIENT_ID_CONFIG(“ client.id”)是在发出请求时传递给服务器的ID,因此服务器可以通过传递生产者名称(例如服务器端请求日志记录)来跟踪IP /端口以外的请求源。
KEY_SERIALIZER_CLASS_CONFIG(“ key.serializer”)是用于Kafka记录键的Kafka序列化器类,该类实现了Kafka序列化器接口。 请注意,由于我们示例中的消息ID为long,因此将其设置为LongSerializer。
VALUE_SERIALIZER_CLASS_CONFIG(“ value.serializer”)是用于Kafka记录值的Kafka序列化器类,该类实现了Kafka序列化器接口。 请注意,由于示例中的消息主体是字符串,因此将其设置为StringSerializer。
与Kafka Producer同步发送记录
Kafka提供了一种同步发送方法,可将记录发送到主题。 让我们使用这种方法将一些消息ID和消息发送到我们之前创建的Kafka主题。
KafkaProducerExample.java-同步发送记录
〜/ kafka-training / lab3 / src / main / java / com / cloudurable / kafka / KafkaProducerExample.java public class KafkaProducerExample { ... static void runProducer(final int sendMessageCount) throws Exception { final Producer<Long, String> producer = createProducer(); long time = System.currentTimeMillis(); try { for (long index = time; index < time + sendMessageCount; index++) { final ProducerRecord<Long, String> record = new ProducerRecord<>(TOPIC, index, "Hello Mom " + index); RecordMetadata metadata = producer.send(record).get(); long elapsedTime = System.currentTimeMillis() - time; System.out.printf("sent record(key=%s value=%s) " + "meta(partition=%d, offset=%d) time=%d\n", record.key(), record.value(), metadata.partition(), metadata.offset(), elapsedTime); } } finally { producer.flush(); producer.close(); } } ...
上面只是遍历了一个for循环,创建了一个ProducerRecord发送一个示例消息(“ Hello Mom” +索引)作为记录值,并将for循环索引作为记录键。 对于每次迭代,runProducer调用生产者的发送方法(RecordMetadata元数据= producer.send(record).get())。 send方法返回Java未来。
响应RecordMetadata具有写入记录的“分区”和该分区中记录的“偏移”。
请注意冲洗和关闭的调用。 Kafka会自动进行自动刷新,但是你也可以显式调用flush,这将立即发送累积的记录。 完成后关闭连接是有礼貌的。
运行 Kafka生产者
接下来,你定义主要方法。
KafkaProducerExample.java-运行生产者
〜/ kafka-training / lab3 / src / main / java / com / cloudurable / kafka / KafkaProducerExample.java public static void main(String... args) throws Exception { if (args.length == 0) { runProducer(5); } else { runProducer(Integer.parseInt(args[0])); } }
主要方法只是调用runProducer。
与Kafka Producer异步发送记录
Kafka提供了一种异步发送方法,可将记录发送到主题。 让我们使用这种方法将一些消息ID和消息发送到我们之前创建的Kafka主题。 这里最大的区别是我们使用lambda表达式定义回调。
KafkaProducerExample.java-与Kafka Producer异步发送记录
〜/ kafka-training / lab3 / src / main / java / com / cloudurable / kafka / KafkaProducerExample.java static void runProducer(final int sendMessageCount) throws InterruptedException { final Producer<Long, String> producer = createProducer(); long time = System.currentTimeMillis(); final CountDownLatch countDownLatch = new CountDownLatch(sendMessageCount); try { for (long index = time; index < time + sendMessageCount; index++) { final ProducerRecord<Long, String> record = new ProducerRecord<>(TOPIC, index, "Hello Mom " + index); producer.send(record, (metadata, exception) -> { long elapsedTime = System.currentTimeMillis() - time; if (metadata != null) { System.out.printf("sent record(key=%s value=%s) " + "meta(partition=%d, offset=%d) time=%d\n", record.key(), record.value(), metadata.partition(), metadata.offset(), elapsedTime); } else { exception.printStackTrace(); } countDownLatch.countDown(); }); } countDownLatch.await(25, TimeUnit.SECONDS); }finally { producer.flush(); producer.close(); } }
注意使用了CountDownLatch,因此我们可以发送所有N条消息,然后等待它们全部发送。
异步接口回调和异步发送方法
Kafka定义了一个用于异步操作的Callback接口。回调接口允许代码在请求完成后执行。回调是在后台I / O线程中执行的,因此它应该是快速的(不要阻止它)。异步操作完成时会调用onCompletion(RecordMetadata元数据,Exception异常)。如果操作成功,则设置元数据(不为null),如果操作出错则设置异常(不为null)。
异步发送方法用于将记录发送到主题,并在确认发送后调用提供的回调。发送方法是异步的,当记录存储在等待发布到Kafka代理的记录缓冲区中时,发送方法将立即返回。发送方法允许并行发送许多记录而不会阻塞以等待每条记录之后的响应。
来自KafkaProducer:``由于发送调用是异步的,因此将为分配给该记录的RecordMetadata返回Future。在此Future上调用get()将阻塞,直到相关请求完成,然后返回记录的元数据或抛出任何发送记录时发生的异常。”
结论Kafka生产者示例
我们创建了一个简单的示例来创建一个Kafka Producer。 首先,我们创建了一个新的复制的Kafka主题; 然后我们用Java创建了Kafka Producer,它使用Kafka复制的主题发送记录。 我们使用异步和同步发送方法通过Kafka Producer发送记录。
评论卡夫卡制片人
回调lambda有什么作用?
请求完成后,回调将得到通知。
如果引导列表中的第一台服务器关闭,将会发生什么? 生产者是否仍可以连接到集群中的其他Kafka经纪人?
生产者将尝试联系列表中的下一个经纪人。 一旦与任何经纪人联系,就会让生产者知道整个Kafka集群。 只要列表中至少有一个代理正在运行,生产者就将连接。 如果你有100个代理,并且引导列表中的三台服务器列表中的两个代理已关闭,则生产者仍可以使用其余98个代理。
什么时候使用Kafka异步发送与同步发送?
如果你已经在使用异步代码(Akka,QBit,Reakt,Vert.x)基础,并且想要快速发送记录。
为什么要为Kafka记录需要两个序列化器?
其中一个序列化程序用于Kafka记录键,另一个用于Kafka记录值。
> 喜欢这篇文章的可以点个赞,欢迎大家留言评论,记得关注我,每天持续更新技术干货、职场趣事、海量面试资料等等
> 如果你对java技术很感兴趣也可以交流学习,共同学习进步。
> 不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代
文章写道这里,欢迎完善交流。最后奉上近期整理出来的一套完整的java架构思维导图,分享给大家对照知识点参考学习。有更多JVM、Mysql、Tomcat、Spring Boot、Spring Cloud、Zookeeper、Kafka、RabbitMQ、RockerMQ、Redis、ELK、Git等Java干货
精选干货 在java中创建kafka的更多相关文章
- Java中创建操作文件和文件夹的工具类
Java中创建操作文件和文件夹的工具类 FileUtils.java import java.io.BufferedInputStream; import java.io.BufferedOutput ...
- JAVA中创建线程的三种方法及比较
JAVA中创建线程的方式有三种,各有优缺点,具体如下: 一.继承Thread类来创建线程 1.创建一个任务类,继承Thread线程类,因为Thread类已经实现了Runnable接口,然后重写run( ...
- Java中创建线程的三种方式以及区别
在java中如果要创建线程的话,一般有3种方法: 继承Thread类: 实现Runnable接口: 使用Callable和Future创建线程. 1. 继承Thread类 继承Thread类的话,必须 ...
- Java中创建数组的几种方法
Java中创建数组的几种方法 public static void main(String[] args) { //创建数组的第一种方法 int[] arr=new int[6]; int intVa ...
- Java中创建实例化对象的几种方式
Java中创建实例化对象有哪些方式? ①最常见的创建对象方法,使用new语句创建一个对象.②通过工厂方法返回对象,例:String s =String.valueOf().(工厂方法涉及到框架)③动用 ...
- Java中创建(实例化)对象的五种方式
Java中创建(实例化)对象的五种方式1.用new语句创建对象,这是最常见的创建对象的方法. 2.通过工厂方法返回对象,如:String str = String.valueOf(23); 3.运用反 ...
- Java中创建的对象多了,必然影响内存和性能
1, Java中创建的对象多了,必然影响内存和性能,所以对象的创建越少越好,最后还要记得销毁.
- java 中创建线程有哪几种方式?
Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行 ...
- Java中创建泛型数组
Java中创建泛型数组 使用泛型时,我想很多人肯定尝试过如下的代码,去创建一个泛型数组 T[] array = new T[]; 当我们写出这样的代码时编译器会报Cannot create a gen ...
随机推荐
- 106、Java中String类之使用contains()方法判断子字符串是否存在
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- Java安全中的“大坑”,跨平台真“浮云”
Java安全HttpDB 最近在做一个开源项目HttpDB,它的目标是在互联网中通过JDBC安全的查询数据库,解决云计算报表的数据库访问问题. 数据传输使用AES加密算法,用到了Java提供的安全库j ...
- 图片FormData上传
var base64String = /*base64图片串*/; //这里对base64串进行操作,去掉url头,并转换为byte var bytes = window.atob(base64Str ...
- Django(十九)文件上传:图片上传(后台上传、自定义上传)、
一.基本设置 参考:https://docs.djangoproject.com/zh-hans/3.0/topics/http/file-uploads/ 1)配置project1/settings ...
- 创建用户(adduser和useradd)和删除用户(userdel)及
一 用户创建命令: # adduser 用户名 # useradd 用户名 1) useradd 与 adduser 的区别 在CentOs系统中: useradd与adduser是没有区别的, ...
- Vue的7属性-8方法-7指令
Vue的7属性: el属性 绑定id,用来指示vue编译器从什么地方开始解析 vue的语法,可以说是一个占位符 data属性 用来组织从view中抽象出来的属性,可以说将视图的数据抽象出来存放在dat ...
- Kubernetes 各版本镜像列表
以下镜像列表由 kubeadm v1.11.1 导出,若使用预下载镜像离线部署的方式部署,请使用 kubeadm v1.11.1 版本 导出各版本镜像列表: kubeadm config images ...
- day01-Python运维开发基础
还是用思维导图来一遍,印象更深!
- mysql悲观锁处理赠品库存超卖的情况
处理库存超卖的情况前,先了解下什么是乐观锁和悲观锁,下面的几篇博客已经介绍的比较详细了,我就不在赘述其原理了 [MySQL]悲观锁&乐观锁 对mysql乐观锁.悲观锁.共享锁.排它锁.行锁.表 ...
- .Net内存回收
研究了好半天的GC.Collect(),遗憾的发现,无法主动控制内存的回收. 只有窗体最小化的时候,内存才回收. 貌似gc.collect只是告诉虚拟机,准备回收内存吧. GC.WaitForPe ...