消息中间件之Kafka入门讲解(二十一)

Kafka在Windows上的使用

1.下载安装并启动Zookeeper

Kafka的运行依赖于Zookeeper,简单点讲:ZooKeeper是一个集中服务,用于维护配置信息,命名,提供分布式同步和提供组服务。它和Kafka一样,都是Apache旗下的组件。如何下载都不赘述,本次演示用的软件都会在底部源代码给出。

下载之后,得到类似zookeeper-3.4.8.zip这样的文件夹,我这里用了一个比较稳定的版本来演示。

之后解压,得到zookeeper-3.4.8文件夹,可以把这个文件夹放到自己的常用软件安装路径下,打开文件夹,再进入conf文件夹,复制zoo_sample.cfg文件到当前文件夹下,重命名为zoo.cfg,如图:


之后进入zookeeper-3.4.8\bin目录,双击zkServer.cmd,启动Zookeeper服务,成功启动之后,可以看到服务占用了2181端口:


2.下载安装并启动Kafka

同样是在Apache上面下载Kafka,下载之后得到kafka_2.11-1.1.0.tgz的压缩包,解压后为了方便,也是可以放到常用软件的安装路径下,打开一个命令行,进入Kafka如下的安装目录:kafka_2.11-1.1.0\bin\windows,之后运行kafka-server-start ../../config/server.properties,用Kafka的server.properties文件来启动Kafka,成功启动之后,Kafka会占用9092端口,与RabbitMQ类似,Kafka也提供了相应的API供我们调用,只不过Kafka没有像RabbitMQ那样比较直观的后台管理界面

3.编写消息生产者和消息消费者

新建一个简单java的maven项目hello-kafka,在pom.xml中引入Kafka的依赖:

<dependencies>
	<dependency>
		<groupId>org.apache.kafka</groupId>
		<artifactId>kafka-clients</artifactId>
		<version>1.1.0</version>
	</dependency>
	<dependency>
		<groupId>org.slf4j</groupId>
		<artifactId>slf4j-log4j12</artifactId>
		<version>1.7.25</version>
	</dependency>
</dependencies>

之后创建org.init.springcloud包,在包下新建SendMessage.class类,用于消息的发送,详细步骤已经写在注释里了:

package org.init.springcloud;

import java.util.Properties;

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;

public class SendMessage {

	public static void main(String[] args) {
		//初始化配置信息
		Properties properties = new Properties();
		properties.put("bootstrap.servers", "localhost:9092");
		//数据key的序列化处理类
		properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
		//数据value的序列化处理类
		properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
		//创建生产者
		Producer<String,String> producer = new KafkaProducer<String,String>(properties);
		//生成一条新的记录,前一个参数是Topic的名称,后面两个对应数据的键值
		ProducerRecord<String,String> record = new ProducerRecord<String,String>("hello-topic","username","spirit");
		//发送记录
		producer.send(record);
		//关闭消息生产者
		producer.close();
	}
	
}

运行main()方法,发送我们的消息。之后新开一个命令行,还是去到kafka_2.11-1.1.0\bin\windows路径下,运行命令:kafka-topics --list --zookeeper localhost:2181,查看Kafka上面有哪些Topic,可以看到我们刚刚发送的hello-topic,已经在Kafka上了:


之后创建一个消息消费者ReceiveMessage.class类来接收消息,代码里写明了详细步骤:

package org.init.springcloud;

import java.util.Arrays;
import java.util.Properties;

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

public class ReceiveMessage {

	public static void main(String[] args) {
		
		//初始化配置信息
		Properties properties = new Properties();
		properties.put("bootstrap.servers", "localhost:9092");
		//指定消费者组(必须!)
		properties.put("group.id", "hello-kafka");
		//数据key的反序列化处理类
		properties.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
		//数据value的反序列化处理类
		properties.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
		//创建消费者
		@SuppressWarnings("resource")
		Consumer<String,String> consumer = new KafkaConsumer<String,String>(properties);
		//订阅hello-topic的信息
		consumer.subscribe(Arrays.asList("hello-topic"));
		//读取消息
		while(true){
			ConsumerRecords<String,String> records = consumer.poll(50);
			for (ConsumerRecord<String, String> record : records) {
				System.out.println("消息的key为:"+record.key()+",消息的值为:"+record.value());
			}
		}
	}
	
}

之后运行main()方法,可以看到控制台输出了我们的信息:


消费者组的概念

我们刚刚在创建消费者的时候,设置了一个消费者组的东西,也就是group.id,它是用于分布式或者集群的。如上图,假设我们有两个消费者:A和B,如果A和B都拥有同一个group.id,那么,当Kafka上面有一条消息广播出来的时候,A和B只有其中一个能接收到消息,这就实现了一个负载的效果;但是如果A和B是属于不同的消费者组,那么当Kafka广播消息的时候,两个消费者A和B就都能接收到消息了。

拷贝ReceiveMessage类生成ReceiveMessageB类,不修改其他信息,只是修改两者的打印信息,对于ReceiveMessage:

System.out.println("消费者A,消息的key为:"+record.key()+",消息的值为:"+record.value());

对于ReceiveMessageB:

System.out.println("消费者B,消息的key为:"+record.key()+",消息的值为:"+record.value());

同时启动这两个类,之后运行SendMessage的main()方法,查看ReceiveMessage和ReceiveMessageB的控制台输出:



可以看到只有ReceiveMessage是输出了信息的,之后我们修改ReceiveMessageB的消费者组:

//指定消费者组(必须!)
properties.put("group.id", "hello-kafka-b");

保存之后,重启ReceiveMessage和ReceiveMessageB,运行SendMessage的main()方法,查看ReceiveMessage和ReceiveMessageB的控制台输出:



源码点击这里

猜你喜欢

转载自blog.csdn.net/mrspirit/article/details/80572082