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());
    }

}

 

 

 

posted on 2023-05-21 17:13  高达  阅读(473)  评论(0)    收藏  举报

导航