官方API文档:Apache Kafka
参考书籍:《kafka权威指南》
注意:kafka的主题只能用命令创建,在代码中无法创建。
1.创建maven项目,配置pom文件:
<dependencies>
<!-- kafka -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies>
2.创建生产者:
package mykafka;
import java.util.Properties;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
/**
* 消息生产者实体类
* @author wyhui
*/
public class MyProducer {
private final static String TOPIC = "besttopic";//定义Topic
private static KafkaProducer<String,String> producer = null;//声明一个KafkaProducer对象,这里的泛型是消息中key和value的类型,我们这里都定义为String类型。
public static void main(String[] args) {
//配置生产者属性并创建生产者
Properties producerProp = new Properties();
producerProp.put("bootstrap.servers","192.168.184.128:9092");//这里的server我们就使用本地的,但是推荐写至少两个,防止其中有一个宕机。多个server用逗号隔开。
producerProp.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");//定义消息中key的类型,我们这里定义为String。
producerProp.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");//定义消息中value的类型,这里我们定义为String。
//属性配置完成后,将属性对象作为参数,传入生产者对象的构造方法中创建生产者
producer = new KafkaProducer<String, String>(producerProp);
//发送消息
/**
* sensd()方法会返回一个包含RecordMetadata的Future对象,
* 不过因为我们会忽略返回值,所以无法知道消息是否发送成功。如果不关心发送結果,那么可以使用这种发送方式。
*/
for(int i = 10;i < 13; i++) {
ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC, Integer.toString(i), Integer.toString(i));//参数分别是主题,消息的key,消息的value
producer.send(record);
}
producer.send(new ProducerRecord<>(TOPIC, "henan", "luoyang"));
producer.send(new ProducerRecord<>(TOPIC, null, "hangzhou"));//key为空
System.out.println("消息发送完毕");
/**
* 同步发送消息:
* send()方法中如果使用一个参数的这个方法那么返回的是一个Future对象,然后调用Future对象的get()方法等待kafka响应。
* 如果服务器返回错误,get()方法会拋出异常。如果没有发生错误,我们会得到一个RecordMetadata对象,可以用它获取消息的offset。
*/
//producer.send(record).get();
/**
* 异步发送消息:
* 在send()方法中需要传入一个实现了org.apache.kafka.clients.producer.Callback这个接口的对象,使用内部类实现onCompletion()方法。
* 如果kafka返回一个错误,onCompletion方法会拋出一个非空异常,这里我们只是把异常信息打印出來,实际业务中可以对其进一步处理。
*/
/*producer.send(record, new Callback() {
@Override
public void onCompletion(RecordMetadata recordMeatadata, Exception e) {
if(e != null) {
e.printStackTrace();
}
}
});*/
producer.close();//关闭生产者
}
}
3.创建消费者:
package mykafka;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Properties;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
/**
* 消息的消費者
* @author wyhui
*
*/
public class MyConsumer {
public static void main(String[] args) {
//配置消费者属性并创建消费者
Properties consumerProp = new Properties();
consumerProp.put("bootstrap.servers","192.168.184.128:9092");//连接kafka集群server,若有多个server,用逗号隔开
consumerProp.put("group.id", "wyhtest");//每个消费者分配独立的group.id,该值不是必需的,它指定了KafkaCosumer属于哪个消费者群组。创建不属于任何一个群组的消費者也是可以的,只是这样做不太常见。
consumerProp.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");//与生产者中的属性类似,不过这里指的是使用指定的类把字节数组转成java对象。
consumerProp.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
consumerProp.put("enable.auto.commit", "true");//消費者自動提交偏移量,提交間隔默認是5s。
consumerProp.put("auto.commit.interval.ms", "30000");//offset的提交間隔
//創建消費者
KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(consumerProp);
// 訂閱主題
consumer.subscribe(Arrays.asList("besttopic"));//subscribe方法接受的是一個Topic列表作為參數,所以需要先創建一個主題列表。方法的參數也可以使用正則表達式匹配多個主題,比如傳入"mytopic.*"進行匹配。
//輪詢
while(true) {//这是一个无限循环。消费者实际上是一个长期运行的应用程序,它通过持续轮询向kafka请求数据。
/**
* poll():消费者必须持续对kafka进行轮询,否则会被认为已经死亡,它的分区会被移交给群组里的其他消费者。
* 传入的参数是一个超时时间,用于控制poll()方法的阻塞时间。
* 返回的是一个记录列表。
*/
ConsumerRecords<String, String> records = consumer.poll(1000);
for(ConsumerRecord<String, String> record : records) {//遍历记录列表
long offset = record.offset();
int partition = record.partition();
Object key = record.key();//返回的是Object
Object value = record.value();
System.out.println("offset:"+offset+",partition:"+partition+",key:"+key+",value:"+value);
}
}
}
}
在启动程序之前要先启动zookeeper和kafka服务。然后启动生产者,再启动消费者。
生产者控制台:
消费者控制台:
我们在去用命令查看一下消费者情况(打印的都是value):
以上就是使用java代码进行kafka通信的简单实现,还有很多参数性质没有仔细研究。在此过程中出现的无法与kafka进行通信的一些问题可以通过下面连接解决,希望有所帮助。