写在前面,此文章意在记录工作中的总结,为他人提供一点点的帮助,对文章的内容欢迎大家提出意见,文章中提到的配置皆在虚拟机当中部署,故不作集群和其他完备处理,意在作简单了解和练习。
Kafka和Zookeeper的关系
Zookeeper在Kafka中扮演重要的角色,用于管理Kafka集群的元数据和实现Kafka集群的协调和管理。Zookeeper在Kafka集群中发挥了重要的角色,它管理着Kafka的发布/订阅机制、Broker状态信息、Topic的元数据信息等,使得Kafka集群的分布式协同和协调变得可能。
Kafka和Zookeeper的安装
- 采用docker安装部署zookeeper和kafka,这里省去docker的安装
- 在开始安装zookeeper和kafka之前需要确认自己的docker环境正常,使用
docker --version
来查看自己的docker版本号,如果出现 即为正常 - 使用
docker pull wurstmeister/kafka:2.13-2.6.0
来拉取kafka的docker镜像,在这一步可能会出现拉取失败,拉取超时,分别对应着版本号错误或者不存在,docker没有配置国内镜像源,请自行百度解决。 - 使用
docker pull zookeeper
来安装kafka的老大哥zooKeeper,当docker命令未指出版本号时,都采用latest版本 -当镜像拉取完毕之后可以通过docker的docker run
命令来创建并且运行容器,再首次创建之后使用docker start
和docker stop
来开启或者关闭容器
- 在开始安装zookeeper和kafka之前需要确认自己的docker环境正常,使用
Kafka和Zookeepr的配置与部署
-
当所有镜像拉取完成之后,可以用
docker images
来查看所有的镜像 -
当容器启动完成之后,使用
docker ps -a
,可以查看所有启动的容器。 -
在确认容器全都启动完成之后可以使用命令
docker exec -it zk /bin/bash
来进入Zookeeper容器内部 来启动Zookeeper客户端,尝试连接zookeeper客户端:zkCli.sh
,最后使用ls /
来确认客户端连接成功。 -
使用
docker exec -it kafka1 /bin/bash
来进入kafka容器内部,在这之前你如果在Zookeeper容器内部无法关闭,可以选中虚拟机窗口,使用ctrl+p+q 来跳出容器内部。 -
当进入容器之后可以运行消息的生产者来发送消息,首先切换
cd /opt/kafka/bin
下,使用./kafka-console-producer.sh --broker-list localhost:9092 --topic sun
来启动一个生产者,当光标变换如下,即进入了消息编辑模式: -
发送消息
-
使用命令
/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic sun --from-beginning
来接收消息 -
当实现了上述过程,即完成了简单的消息生产和消费,但是!怎么能缺少Java参与!
- 用Java创建一个生产者
java
package com.example.kafka;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;
import java.util.Properties;
public class Producer {
public static String topic = "message_test"; //主题
public static void main(String[] args) throws InterruptedException {
Properties pro = new Properties();
pro.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.49.128:9092"); //配置ip地址
pro.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); //配置key
pro.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class); //配置Value
pro.put(ProducerConfig.REQUEST_TIMEOUT_MS_CONFIG,"50000000");
pro.put(ProducerConfig.TIMEOUT_CONFIG,"50000000");
pro.put(ProducerConfig.RETRIES_CONFIG, 3);
KafkaProducer<String,String> kafkaProducer = new KafkaProducer<>(pro);
try {
while(true){
String msg = "hellowrold";
ProducerRecord<String,String> producerRecord = new ProducerRecord<>(topic,msg);
kafkaProducer.send(producerRecord);
System.out.println("消息发送成功");
Thread.sleep(50000);
}
}finally {
kafkaProducer.close();
}
}
- 用Java实现一个消费者
java
package com.example.kafka;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;
import java.util.Collections;
import java.util.Properties;
public class Consumer {
public static void main(String[] args) {
Properties p = new Properties();
p.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.49.128:9092");
p.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
p.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
p.put(ConsumerConfig.GROUP_ID_CONFIG, "message_test");
KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<String, String>(p);
kafkaConsumer.subscribe(Collections.singletonList(Producer.topic));// 订阅消息
while (true) {
ConsumerRecords<String, String> records = kafkaConsumer.poll(100);
for (ConsumerRecord<String, String> record : records) {
System.out.println(String.format("topic:%s,offset:%d,消息:%s", //
record.topic(), record.offset(), record.value()));
}
}
}
当我们依次运行生产者和消费者,消息就可以被生产和消费啦!
总结
今天遇到用java代码链接kafka超时失败,设置了超时时间仍然没有成功,后重新启动虚拟机,先开Zookeeper后开kafka就运行正常了,猜测原因可能是虚拟机挂起状态回复,使得kafka没有正确被注册到Zookeeper上。 有两个比较好用的可视化客户端软件可以更直观的观察到消息的生产和消费这里记录地址,以后备用。 kafka tool 和 ZooInspector