kafka在java程序中实现生产者与消费者的应用

官方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进行通信的一些问题可以通过下面连接解决,希望有所帮助。

使用java代码连接不上kafka的解决方案(生产者与消费者都没能连上)_QYHuiiQ的博客-CSDN博客

项目源码:https://github.com/wyhuiii/kafka

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

QYHuiiQ

听说打赏的人工资翻倍~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值