Kafka3.7.X使用学习文档

182 阅读5分钟

一. Kafka3.7.X使用文档:

1, kafka的下载地址:

Apache Kafka


2, 解压缩kafka压缩包:

放在目录下,列如: D:\SoftWare\Kafka

二. kafka的启动流程(Windows):

1, ZooKeeper启动:

  1. 进入kafka/config目录下,修改zookeeper.properties配置文件:
#修改数据储存位置:
dataDir=D:/SoftWare/Kafka/data/zk

  1. 打开cmd黑窗口执行zookeeper启动脚本:
zookeeper-server-start.bat ../../config/zookeeper.properties

  1. 或者使用脚本自行启动dos:
call bin/windows/zookeeper-server-start.bat config/zookeeper.properties

2, Kafka启动:


  1. 进入kafka/config目录下,修改server.properties配置文件:
log.dirs=D:/kafka/data/kafka

  1. 使用脚本dos自行启动kafka:
call bin/windows/kafka-server-start.bat config/server.properties

3, 启停顺序:


启动时:  先启动zookeeper再启动kafka;
#==========
关闭时:  先关闭kafka再关闭zookeeper;

4, 查看进程:

  1. 在kafka的目录下,打开dos窗口:
#使用如下命令即可查看kafka相关进程:
jps

三. Kafka的基础结构:

kafkaStructure.png


1, Producer:

  • Producer消息生产者: 连接broker,并把消息发送到某一个分区中,如Partition0, Partition1, Partition2。

2, Consumer:

  • Consumer消息消费者: 每个消费者都属于某一个Consumer Group(消费者组),一个消费者组内的消费者,
  • 只能有一个消费某个分区(Partition)的消息,但不同组的消费者,可以消费同一个分区的消息。

3, Broker:

  • 一台Kafka服务就是一个Broker。

4, Partition:

  • Partition分区: 每个分区是一个有序的队列,用于存放消息。

5, ZooKeeper:

  • 它可以作为配置中心,生产者,消费者,Broker,topic都需要在ZooKeeper上进行注册。

四. 创建一个Topic:

  1. 在kafka的主目录下,打开dos窗口创建一个Kafka的Topic:
.\bin\windows\kafka-topics.bat --create -bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic FirstTopic
  1. 参数配置的解释:
  • replication-factor(副本因子):

    副本因子是个正整数,表示每个分区的副本数量。

    副本因子应该不大于broker的数量,以避免副本在同一台机器上,这可能会导致数据丢失。

    设置副本因子为2或3通常是比较常见的,因为它提供了一定程度的容错性。

    如果数据对可靠性要求很高,那么需要设置较高的副本因子。


  • partitions(分区):

    Kafka topic的分区数量是一个正整数,可以设置为1到2^31-1之间的值。

    分区数量应该根据数据吞吐量和容错需求来确定。一个较大的分区数量可以提高并发性,但也会增加管理开销。

    通常情况下,分区数量不应该超过集群中broker的数量,因为broker的数量决定了topic的最大并行处理能力。

    如果会有大量的数据写入,应该从一开始就规划好足够的分区数量,因为增加分区数量之后再进行扩展可能会比较复杂。


1, 查看Topic:

  1. 在kafka的主目录下,打开dos窗口查看Topic信息:
.\bin\windows\kafka-topics.bat --describe --topic FirstTopic --bootstrap-server localhost:9092

  1. 参数信息的解释:
  • partiotionCount: 当前Topic的分区总数。

  • replicationFactor: 当前Topic的副本总数。

  • leader: 代表分区的leader在哪个broker上,0代表Leader在broker.id = 0上。

  • Relicas: 列出所有的副本在哪些broker上,一个leader可以有多个不同的follower,0代表此副本在broker.id = 0上,

  • Isr (In-Sync Replicas): 代表的是一个分区的所有副本中,与leader同步的副本集合。

    ISR集合中的副本负责接收和处理来自producer的消息。 当producer发送消息到一个topic的某个分区时,它只会将消息发送到ISR集合中的某个副本(通常是leader副本)。 如果leader副本失败了,Kafka会从ISR集合中选择一个新的leader副本。 ISR的存在确保了如果某个副本失效,数据不会丢失,因为ISR中的副本可以作为新的leader继续提供服务。


  1. 查看当前所有topic:
.\bin\windows\kafka-topics.bat --list --bootstrap-server localhost:9092

五. kafka的生产和消费:

1, 启动消费者:

  • 在kafka的主目录下,打开dos窗口,启动Consumer:
.\bin\windows\kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic FirstTopic
  • 查看该Consumer的某个Topic是否有消费消息:
.\bin\windows\kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic FirstTopic --from-beginning

2, 启动生产者:

  • 在kafka的主目录下,打开dos窗口,启动Producer:
.\bin\windows\kafka-console-producer.bat --broker-list localhost:9092 --topic FirstTopic

3, 服务的关闭顺序:

生产者和消费者 --> kafka --> zookeeper;


六. SpringBoot整合Kafka:

1. 搭建一个父工程:

  1. 父工程Pom.xml导入依赖:
	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>org.example</groupId>
    <artifactId>kafkatest</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>kafka-consumer</module>
        <module>kafka-producer</module>
    </modules>

    <dependencies>
        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
        </dependency>
        <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>
        </dependency>
    </dependencies>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

2. 搭建Producer子工程:

  1. 子工程的pom.xml,继承父工程的依赖:
	<parent>
        <groupId>org.example</groupId>
        <artifactId>kafkatest</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>kafka-producer</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

  1. 创建SpringBoot启动类:
@SpringBootApplication
@EnableScheduling
public class SpringProducer {
    public static void main(String[] args) {
        SpringApplication.run(SpringProducer.class, args);
    }
}

  1. 创建application.yml文件:
server:
  port: 8090
  
spring:
  kafka:
    bootstrap-servers: localhost:9092
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
      acks: all
      retries: 0

  1. 搭建一个ProducerConfig类:
@Configuration
public class ProducerConfig {

    @Value("${spring.kafka.bootstrap-servers}")
    private String bootstrapServers;
    @Value("${spring.kafka.producer.key-serializer}")
    private String keySerializer;
    @Value("${spring.kafka.producer.value-serializer}")
    private String valueSerializer;

    @Bean
    public Map<String, Object> getProps() {
        HashMap<String, Object> props = new HashMap<>();
        props.put("bootstrap.servers", bootstrapServers);
        props.put("key.serializer", keySerializer);
        props.put("value.serializer", valueSerializer);
        return props;
    }

    @Bean
    public ProducerFactory<String, Object> producerFactory() {
        return new DefaultKafkaProducerFactory<>(getProps());
    }

    @Bean
    public KafkaTemplate<String, Object> kafkaTemplate() {
        return new KafkaTemplate<>(producerFactory());
    }

}

  1. 搭建一个Service类,用于写业务代码:
  • 这里用于发送十条消息。
@Service("kafkaService")
public class KafkaSendService {

    @Resource
    private KafkaTemplate<String, Object> kafkaTemplate;

    public void send() {
        for (int i = 0; i < 10; i++) {
            kafkaTemplate.send("FirstTopic", "Hello,Kafka!" + i).addCallback(success -> System.out.println("消息发送成功: " + success), ex -> System.out.println("消息发送失败: " + ex));
        }
    }
}

  1. 创建定时任务用于测试:
@Component
public class SendMsg {

    @Resource private KafkaSendService kafkaSendService;

    @Scheduled(cron = "0/10 * * * * *")//10秒运行一次
    public void sendMsg(){
        kafkaSendService.send();
    }

}

3.搭建Consumer子工程:

  1. 子工程的pom.xml,继承父工程的依赖:
	<parent>
        <groupId>org.example</groupId>
        <artifactId>kafkatest</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>kafka-consumer</artifactId>

  1. 创建SpringBoot启动类:
@SpringBootApplication
@EnableScheduling
public class SpringConsumer {
    public static void main(String[] args) {
        SpringApplication.run(SpringConsumer.class, args);
    }
}

  1. 创建application.yml文件:
server:
  port: 8080
  
spring:
  kafka:
    bootstrap-servers: localhost:9092
    consumer:
      group-id: test-group
      auto-commit-interval: 1000
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      enable-auto-commit: true

  1. 搭建一个ConsumerConfig类:
@Configuration
@EnableKafka
public class ConsumerConfig {
    @Value("${spring.kafka.bootstrap-servers}")
    private String bootstrapServers;
    @Value("${spring.kafka.consumer.group-id}")
    private String groupId;
    @Value("${spring.kafka.consumer.key-deserializer}")
    private String keyDeserializer;
    @Value("${spring.kafka.consumer.value-deserializer}")
    private String valueDeserializer;

    @Bean
    public Map<String, Object> getProps() {
        HashMap<String, Object> props = new HashMap<>();
        props.put("bootstrap.servers", bootstrapServers);
        props.put("group.id", groupId);
        props.put("key.deserializer", keyDeserializer);
        props.put("value.deserializer", valueDeserializer);
        return props;
    }

    @Bean
    public KafkaConsumer<String, Object> kafkaConsumer() {
        return new KafkaConsumer<>(getProps());
    }

    @Bean
    public ConsumerFactory<String, Object> consumerFactory() {
        return new DefaultKafkaConsumerFactory<>(getProps());
    }

    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, Object> listenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<String, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        return factory;
    }


}

  1. 搭建一个Service类,用于写业务代码:
  • 接受并打印该Topic收到的消息:
@Service("msgService")
public class MsgService {

    @Resource
    private KafkaConsumer<String, Object> kafkaConsumer;

    @KafkaListener(topics = {"FirstTopic"}, groupId = "test-group")//监听该Topic
    public void getMsg(string msg) {
        //是否需要对数据进行处理...
        System.out.println("收到来自test-group的消息: " + msg);
    }
}

七. 编程式创建Topic:

1. 创建一个TopicConfig类:

@Configuration
//编程式创建topic
public class KafkaTopicConfig {

    private static final String FIRST_TOPIC = "FirstTopic";

    @Resource
    private ConsumerConfig config;

    @Bean
    public KafkaAdmin kafkaAdmin() {
        return new KafkaAdmin(config.getProps());
    }

    @Bean
    public NewTopic topic() {
        return new NewTopic(FIRST_TOPIC, 1, (short) 1);
    }
}