Docker搭建kafka和zookpeer练手案例
学习文档:
Zookeeper与Kafka基础概念和原理
https://www.cnblogs.com/FengGeBlog/p/10582626.html
原理图:

第一步 搭建zookeeper环境
在centos中,拉取zookeeper镜像,以及创建zookeeper容器
docker pull wurstmeister/zookeeper 拉取 docker run -d --restart=always --log-driver json-file --log-opt max-size=100m --log-opt max-file=2 --name zookeeper -p 2181:2181 -v /etc/localtime:/etc/localtime wurstmeister/zookeeper
命令中的各个参数含义如下:
-d:将容器放在后台运行。--restart=always:在容器退出时自动重启容器。--log-driver json-file --log-opt max-size=100m --log-opt max-file=2:设置日志记录选项。--name zookeeper:给容器设置名称,这里设置为"zookeeper"。-p 2181:2181:将容器内部的2181端口映射到主机的2181端口,这是Zookeeper默认端口。-v /etc/localtime:/etc/localtime:将主机系统的本地时间配置映射到容器中,确保容器和主机的时间同步。wurstmeister/zookeeper:指定要运行的镜像名称
第二步 创建kafka环境
在centos中,创建kafka容器:
docker pull wurstmeister/kafka docker run -d --restart=always --log-driver json-file --log-opt max-size=100m --log-opt max-file=2 --name kafka -p 9092:9092 -e KAFKA_BROKER_ID=0 -e KAFKA_ZOOKEEPER_CONNECT=39.98.222.253:2181/kafka -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://39.98.222.253:9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 -v /etc/localtime:/etc/localtime wurstmeister/kafka
其中,各个参数分别表示:
-d:将容器放在后台运行。--restart=always:在容器退出时自动重启容器。--log-driver json-file --log-opt max-size=100m --log-opt max-file=2:设置日志记录选项。--name kafka:给容器设置名称,这里设置为"kafka"。-p 9092:9092:将容器内部的9092端口映射到主机的9092端口,这是Kafka默认端口。-e KAFKA_BROKER_ID=0:指定此Kafka服务器的唯一ID,避免与其他Kafka服务器重复。-e KAFKA_ZOOKEEPER_CONNECT=39.98.222.253:2181/kafka:指定此Kafka服务器要连接的Zookeeper节点的地址,其中39.98.222.253是Zookeeper节点的IP地址,2181是Zookeeper端口号,“/kafka”是Zookeeper中Kafka数据存储的路径。-e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://39.98.222.253:9092:指定Kafka服务器所在的IP地址和端口。-e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092:指定监听Kafka连接的地址和端口。此处使用0.0.0.0代表监听任何可用网络接口。-v /etc/localtime:/etc/localtime:将主机系统的本地时间配置映射到容器中,确保容器和主机的时间同步。wurstmeister/kafka:指定要运行的镜像名称。
第三步:验证kafka 生产者-消息者模式能否使用
进入容器
$ docker exec -it kafka bash
进入 /opt/kafka_2.13-2.8.1/bin/ 目录下
$ cd /opt/kafka_2.13-2.8.1/bin/
运行kafka生产者发送消息
$ ./kafka-console-producer.sh --broker-list localhost:9092 --topic sun
发送消息
{"datas":[{"channel":"","metric":"temperature","producer":"ijinus","sn":"IJA0101-00002245","time":"1543207156000","value":"80"}],"ver":"1.0"}

执行上诉命令后,另起一个标签页,执行如下命令 创建kafka消费者消费消息:
运行kafka消费者接收消息
$ ./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic sun --from-beginning

第四步:验证topic主题模式
进入到kafka容器中 并创建topic 生产者,执行如下命令:
1)docker exec -it kafka bash 2)cd /opt/kafka_2.13-2.8.1/bin/ 3)./kafka-topics.sh --create --zookeeper 39.98.222.253:2181/kafka --replication-factor 1 --partitions 1 --topic mykafka 4)./kafka-console-producer.sh --broker-list localhost:9092 --topic mykafka

执行上诉命令后,另起一个标签页,执行如下命令 创建kafka消费者消费消息:
1)docker exec -it kafka bash
2)cd /opt/kafka_2.13-2.8.1/bin/4)./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic mykafka --from-beginning

问题
1. fafka启动后,通过docker exec -it kafka bash进入后,不一会儿,自动退出来了。
【问题原因】启动容器设置了--restart=always,通过日志发现启动失败,一直在重启。并指向host不可达

【解决方案】关闭防火墙
systemctl stop firewalld
2、关闭防火墙后重启container失败
docker start 8dfac2df549c
Error response from daemon: driver failed programming external connectivity on endpoint kafka (2bb0b0d19ea751146218f99d3f496db714dd0bc19105663b71fc56f65ebb0592): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9092 -j DNAT --to-destination 172.17.0.3:9092 ! -i docker0: iptables: No chain/target/match by that name
【问题原因】关闭防火墙可能会清空iptables表,需要重建
【解决方案】重启docker
systemctl restart docker
3.提示我broker少于副本数【Error】Error while executing topic command : Replication factor: 1 larger than available brokers: 0
root@315556ad0d2f:/opt/kafka_2.13-2.8.1/bin# ./kafka-topics.sh --create --zookeeper 39.98.222.253:2181 --replication-factor 1 --partitions 8 --topic test
Error while executing topic command : Replication factor: 1 larger than available brokers: 0.
[2023-05-21 11:39:04,408] ERROR org.apache.kafka.common.errors.InvalidReplicationFactorException: Replication factor: 1 larger than available brokers: 0.
(kafka.admin.TopicCommand$)
root@315556ad0d2f:/opt/kafka_2.13-2.8.1/bin#

错误: --zookeeper 39.98.222.253:2181没有加/kafka
./kafka-topics.sh --create --zookeeper 39.98.222.253:2181 --replication-factor 1 --partitions 1 --topic mykafka
正确:
./kafka-topics.sh --create --zookeeper 39.98.222.253:2181/kafka --replication-factor 1 --partitions 1 --topic mykafka
springBoot集成Kafka
链接:https://pan.baidu.com/s/1jXNwn7uEpQFilCsWWqMW_Q?pwd=pxlc
提取码:pxlc
1.引用
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.12.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>kafka</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--org.springframework.kafka--> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.配置yml
server: port: 8088 #服务端口 spring: application: name: auth-api #服务名称 kafka: bootstrap-servers: 39.98.222.253:9092 #Kafka集群的IP地址和端口号,用于建立与Kafka的连接。 consumer: group-id: default-group #消费者组的ID。多个消费者可以组成一个消费者组,以平衡消息处理负载并实现高可用性 enable-auto-commit: false #是否启用自动提交offset。如果为true,则消费者每隔一段时间会自动将最新的offset提交到Kafka。如果设置为false,则需要手动通过代码来提交offset。在手动提交offset时,请确保与spring.kafka.listener.ack-mode属性配合使用,以指定ack(确认)模式。
3.实现生产消息
package kafka.demo.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @RestController @Slf4j @RequestMapping("/kafka") public class kafkaController { @Autowired private KafkaTemplate<String,String> kafkaTemplate; /** * 消费者端:指定监听话题 * 指定监听的topics消息 * @param consumerRecord 监听到数据 */ @RequestMapping("/send") public String sendMessage() { // 创建一个DateTimeFormatter对象 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 获取当前时间 LocalDateTime now = LocalDateTime.now(); // 将日期时间格式化为字符串 String currentTime = now.format(formatter); // 输出当前时间字符串 System.out.println("当前时间是:" + currentTime); // 发送消息到kafka // 需要使用KafkaTemplate String topic = "spring_test_169"; kafkaTemplate.send(topic,"hello spring boot kafka!"+currentTime); log.info("发送成功"); return "发送成功."; } }
4.消费消息
package kafka.demo.service; import lombok.extern.slf4j.Slf4j; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Service; import javax.websocket.SendResult; @Service @Slf4j public class KafkaService { /** * 消费者端:指定监听话题 * * @param consumerRecord 监听到数据 */ @KafkaListener(topics = {"spring_test_169"}) public void handlerMsg(ConsumerRecord<String, String> consumerRecord) { log.info("接收到消息:消息值:" + consumerRecord.value() + ", 消息偏移量:" + consumerRecord.offset()); } }
浙公网安备 33010602011771号