搭建Kafka简单教程

1.前言:

本文只是简单介绍如何搭建kafka,关于kafka的详细内容,此文暂时不讲。

2.Kafka简介

Kafka是分布式发布-订阅消息系统,它最初由 LinkedIn 公司开发,使用 Scala语言编写,之后成为 Apache 项目的一部分。在Kafka集群中,没有“中心主节点”的概念,集群中所有的服务器都是对等的,因此,可以在不做任何配置的更改的情况下实现服务器的的添加与删除,同样的消息的生产者和消费者也能够做到随意重启和机器的上下线。

2.1.Kafka术语介绍

1.消息生产者:即:Producer,是消息的产生的源头,负责生成消息并发送到Kafka服务器上。

2.消息消费者:即:Consumer,是消息的使用方,负责消费Kafka服务器上的消息。

3.主题:即:Topic,由用户定义并配置在Kafka服务器,用于建立生产者和消息者之间的订阅关系:生产者发送消息到指定的Topic下,消息者从这个Topic下消费消息。

4.消息分区:即:Partition,一个Topic下面会分为很多分区,例如:“kafka-test”这个Topic下可以分为6个分区,分别由两台服务器提供,那么通常可以配置为让每台服务器提供3个分区,假如服务器ID分别为0、1,则所有的分区为0-0、0-1、0-2和1-0、1-1、1-2。Topic物理上的分组,一个 topic可以分为多个 partition,每个 partition 是一个有序的队列。partition中的每条消息都会被分配一个有序的 id(offset)。

5.Broker:即Kafka的服务器,用户存储消息,Kafa集群中的一台或多台服务器统称为 broker。

6.消费者分组:Group,用于归组同类消费者,在Kafka中,多个消费者可以共同消息一个Topic下的消息,每个消费者消费其中的部分消息,这些消费者就组成了一个分组,拥有同一个分组名称,通常也被称为消费者集群。

7.Offset:消息存储在Kafka的Broker上,消费者拉取消息数据的过程中需要知道消息在文件中的偏移量,这个偏移量就是所谓的Offset。

3.搭建Kafka
 

3.1. 安装JDK
3.1.1 安装文件:http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html下载Server JRE.
3.1.2 安装完成后需要添加以下的环境变量(右键点击“我的电脑” -> "高级系统设置" -> "环境变量" ):
<1>.JAVA_HOME: C:\Program Files (x86)\Java\jre1.8.0_60(这个是默认安装路径,如果安装过程中更改了安装目录,把更改后的路径填上就行了)
<2>.PATH: 在现有的值后面添加"; %JAVA_HOME%\bin"
3.1.3 打开cmd运行 "java -version" 查看当前系统Java的版本:
3.2. 安装Zookeeper
Kafka的运行依赖于Zookeeper,所以在运行Kafka之前我们需要安装并运行Zookeeper
3.2.1 下载安装文件: http://zookeeper.apache.org/releases.html
3.2.2 解压文件(本文解压到 D:\Software\Devolopment\zookeeper-3.4.14)
3.2.3 打开D:\Software\Devolopment\zookeeper-3.4.14\conf,把zoo_sample.cfg重命名成zoo.cfg
3.2.4 从文本编辑器里打开zoo.cfg
3.2.5 把dataDir的值改成“D:\Software\Devolopment\zookeeper-3.4.14\data”
3.2.6 添加如下系统变量:
<1>.ZOOKEEPER_HOME: D:\Software\Devolopment\zookeeper-3.4.14
<2>.Path: 在现有的值后面添加";%ZOOKEEPER_HOME%\bin;"
3.2.7 运行Zookeeper: 打开cmd然后执行zkserver
3.3. 安装并运行Kafka
3.3.1 下载安装文件: http://kafka.apache.org/downloads.html
3.3.2 解压文件(本文解压到 D:\Software\Devolopment\kafka_2.12-0.10.2.2)
3.3.3 打开D:\Software\Devolopment\kafka_2.12-0.10.2.2\config
3.3.4 从文本编辑器里打开 server.properties
3.3.5 把log.dirs的值改成 “D:\Software\Devolopment\kafka_2.12-0.10.2.2\kafka-logs”
3.3.6 打开cmd
3.3.7 进入kafka文件目录: cd /d D:\Software\Devolopment\kafka_2.12-0.10.2.2
3.3.8 输入并执行以打开kafka:
.\bin\windows\kafka-server-start.bat .\config\server.properties
3.4. 创建topics
3.4.1 打开cmd 并进入D:\Software\Devolopment\kafka_2.12-0.10.2.2\bin\windows
3.4.2 创建一个topic:
kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
3.5.打开一个Producer:
cd D:\Software\Devolopment\kafka_2.12-0.10.2.2\bin\windows
kafka-console-producer.bat --broker-list localhost:9092 --topic test
3.6. 打开一个Consumer:
cd D:\Software\Devolopment\kafka_2.12-0.10.2.2\bin\windows
kafka-console-consumer.bat --zookeeper localhost:2181 --topic test
然后就可以在Producer控制台窗口输入消息了。在消息输入过后,很快Consumer窗口就会显示出Producer发送的消息。
Kafka运行环境的搭建就完成了。

4.代码实现

需要建一个springboot项目,并导入相关依赖。

4.1 添加依赖

<dependency>
   <groupId>org.springframework.kafka</groupId>
   <artifactId>spring-kafka</artifactId>
</dependency>

4.2 配置

package com.example.kafka.kafka2;

import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.EnableKafka;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.config.KafkaListenerContainerFactory;
import org.springframework.kafka.core.*;
import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;

import java.util.HashMap;
import java.util.Map;

@Configuration
@EnableKafka
public class KafkaConfig {

    @Value("localhost:9092")
    private String kafkaServer;

    @Value("defaultGroup")
    private String kafkaGroup;

    public Map<String, Object> consumerConfig(String consumerGroupId){
        Map<String, Object> props = new HashMap<>();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaServer);
        props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
        props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "100");
        props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "15000");
        props.put(ConsumerConfig.GROUP_ID_CONFIG, consumerGroupId);
        props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        return props;
    }
    public ConsumerFactory<String, String> consumerFactory(String consumerGroupId) {
        return new DefaultKafkaConsumerFactory<>(consumerConfig(consumerGroupId));
    }

    public Map<String, Object> producerConfig(){
        Map<String, Object> props = new HashMap<>();
        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaServer);
        props.put(ProducerConfig.RETRIES_CONFIG, 0);
        props.put(ProducerConfig.BATCH_SIZE_CONFIG, 1000);
        props.put(ProducerConfig.LINGER_MS_CONFIG, 1);
        props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, 40960);
        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        return props;
    }

    public ProducerFactory<String, String> producerFactory(){
        return new DefaultKafkaProducerFactory<>(producerConfig());
    }


    @Bean(name="kafkaListenerContainerFactory")
    public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory(kafkaGroup));
        factory.setConcurrency(3);
        factory.getContainerProperties().setPollTimeout(3000);
        return factory;
    }

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

}

4.3 生产者

package com.example.kafka.kafka2;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Component
public class KafkaSender {
    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    @Value("test")
    private String topic;

    private int index;
    public void sendTest(){
        String msg = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
        kafkaTemplate.send(topic,"hello,kafka"+index + ":" + msg);
        System.out.println("hello,kafka"+index + ":" + msg);
        index ++;

    }
}

4.4 消费者

package com.example.kafka.kafka2;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.DependsOn;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;

@Component
public class KafkaConsumer {

    /**
     * 监听test主题,有消息就读取
     * @param message
     */
    @KafkaListener(topics="test",containerFactory="kafkaListenerContainerFactory")
    public void consumer(String message){
        System.out.println("receiveMaching1:"+ message);
    }
}

4.5 调用生产者Controller

package com.kafka.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class KafkaController {

    @Autowired
    private KafkaSender kafkaSender;

    @RequestMapping(value = "send",method = RequestMethod.GET)
    public String send(String type){
        kafkaSender.sendTest();
        return "OK";
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值