消息中间件之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的控制台输出:

源码点击这里

最后,大家有什么不懂的或者其他需要交流的内容,也可以进入我的QQ讨论群一起讨论:654331206

Spring Cloud系列:

Spring Cloud介绍与环境搭建(一)

Spring Boot的简单使用(二)

Spring Cloud服务管理框架Eureka简单示例(三)

Spring Cloud服务管理框架Eureka项目集群(四)

Spring Cloud之Eureka客户端健康检测(五)

Netflix之第一个Ribbon程序(六)

Ribbon负载均衡器详细介绍(七)

Spring Cloud中使用Ribbon(八)

具有负载均衡功能的RestTemplate底层原理(九)

OpenFeign之第一个Feign程序(十)

OpenFeign之feign使用简介(十一)

Spring Cloud中使用Feign(十二)

Netflix之第一个Hystrix程序(十三)

Netflix之Hystrix详细分析(十四)

Spring Cloud中使用Hystrix(十五)

Netflix之第一个Zuul程序(十六)

Spring Cloud集群中使用Zuul(十七)

Netflix之Zuul的进阶应用(十八)

消息驱动之背景概述(十九)

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

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

Spring Cloud整合RabbitMQ或Kafka消息驱动(二十二)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值