kafka基础配置+kafka与java结合

1. 配置虚拟机

1.1 IP和主机名称配置

1.1.1 vm配置

image-20220616105742532

打开后,右下角,管理员权限修改,然后vm8,子网IP随意,(1,2,3,4,5...)

NAT设置,将网关IP与子网IP一致,192.168.10.2

image-20220616105908644

1.1.2 win配置

如果没有vm8,将上面的还原默认设置

image-20220616141355626

image-20220616141621925

1.1.3 centos配置

如果是安装的最小安装系统

  • 首先要安装net-tool:工具包合集,包含ifconfig等命令

    yum install -y net-tools

  • vim:编辑器

    yum install -y vim

  1. 切换到root用户

    su root
    
  2. 修改ip地址

    vim /etc/sysconfig/network-scripts/ifcfg-ens33 #注意文件名字,建议cd打开到当前目录,然后ll命令,查看文件名字,我的不是ens33
    

    改动态获取ip为静态ip

    BOOTPROTO = "static"
    
    #文件末尾加
    IPADDR = 192.168.10.100
    #网关
    GATEWAY = 192.168.10.2
    #域名解析器
    DNS1 = 192.168.10.2
    

    按ESC,输入wq保存退出

  3. 修改主机名称

    vim /etc/hostname 
    

    修改为hadoop100

  4. 主机名称映射

    vim /etc/hosts
    

    文档末尾添加

    192.168.10.100 hadoop100
    192.168.10.101 hadoop101
    192.168.10.102 hadoop102
    192.168.10.103 hadoop103
    192.168.10.104 hadoop104
    192.168.10.105 hadoop105
    192.168.10.106 hadoop106
    192.168.10.107 hadoop107
    
  5. reboot重启

  6. 测试

    #查看ip地址是否正确
    ifconfig
    #查看网络是否可用
    ping www.baidu.com
    #查看主机名称
    hostname
    

1.2 xshell远程访问

新建连接即可,略过

1.2.1修改主机映射

C:\Windows\System32\drivers\etc\hosts

在文件末尾加上

192.168.10.100 hadoop100
192.168.10.101 hadoop101
192.168.10.102 hadoop102
192.168.10.103 hadoop103
192.168.10.104 hadoop104
192.168.10.105 hadoop105
192.168.10.106 hadoop106
192.168.10.107 hadoop107

建立连接时可以直接

1.3 模板虚拟机搭建

1.3.1 安装epel-release

yum install -y epel-release

1.3.2 创建文件夹,并修改所属组

  1. /opt目录下创建module、software文件夹

    [root@hadoop100 ~]# mkdir /opt/module
    [root@hadoop100 ~]# mkdir /opt/software
    
  2. 修改两个文件夹的所有者和所属组

    [root@hadoop100 opt]# chown luomuchen:luomuchen /opt/module
    [root@hadoop100 opt]# chown luomuchen:luomuchen /opt/software
    

2. 开始配置kafka

2.1 安装前准备

  1. 需要zookeeper包,java1.8包,以及kafka包

  2. 虚拟机安装lrzsz这样可以省略ftp相关的一些指令

    yum install -y lrzsz
    
  3. 输入rz可以将安装包传入虚拟机中

    image-20220616152135487

  4. 解压安装包

    [root@hadoop100 software]# tar -zxvf jdk-8u333-linux-x64.tar.gz -C /opt/module
    [root@hadoop100 software]# tar -zxvf kafka_2.12-3.2.0.tgz -C /opt/module
    [root@hadoop100 software]# tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz -C /opt/module
    
  5. 配置JDK的环境变量

    vim /etc/profile
    

    在这个文件最后,配置JAVA_HOME

    ## JAVA_HOME
    export JAVA_HOME=/opt/module/jdk1.8.0_333
    
    ## PATH
    export PATH=$PATH:$JAVA_HOME/bin
    

    重启资源

    [root@hadoop100 etc]# source /etc/profile
    

    然后查看是否配置成功(java -version)

  6. 配置zookeeper

    在conf目录下,修改 zoo_sample.cfg名字为 zoo.cfg

    mv zoo_sample.cfg zoo.cfg 
    

    配置zoo.cfg

    image-20220616160017741

  7. zookeeper相关指令

    [root@hadoop100 apache-zookeeper-3.7.1-bin]# bin/zkServer.sh start
    [root@hadoop100 apache-zookeeper-3.7.1-bin]# bin/zkServer.sh stop
    

2.2 开始配置kafka

  1. config目录下,修改server.properties

    #kafka 运行日志(数据)存放的路径,路径不需要提前创建,kafka 自动帮你创建,可以
    配置多个磁盘路径,路径与路径之间可以用","分隔
    log.dirs=/opt/module/kafka/datas
    #配置连接 Zookeeper 集群地址(在 zk 根目录下创建/kafka,方便管理)
    #zookeeper.connect=hadoop102:2181,hadoop103:2181,hadoop104:2181/kafka
    #由于我只有一台,所以改为这样就可
    zookeeper.connect=localhost:2181/kafka
    
  2. 配置环境变量,同java

    ## KAFKA_HOME
    export KAFKA_HOME=/opt/module/kafka_2.12-3.2.0
    export PATH=$PATH:$KAFKA_HOME/bin
    

2.3 启动kafka

先启动zookeeper,然后启动kafka

[root@hadoop100 apache-zookeeper-3.7.1-bin]# bin/zkServer.sh start
[root@hadoop100 kafka_2.12-3.2.0]# bin/kafka-server-start.sh -daemon config/server.properties
/opt/module/apache-zookeeper-3.7.1-bin/bin/zkServer.sh start
/opt/module/kafka_2.12-3.2.0/bin/kafka-server-start.sh -daemon /opt/module/kafka_2.12-3.2.0/config/server.properties 

3. 开始使用kafka

3.1 生产者

  1. kafka操作主题(topic)的命令参数

    image-20220616222630464

  2. 查看所有topic列表

    [luomuchen@hadoop100 kafka_2.12-3.2.0]$ bin/kafka-topics.sh --bootstrap-server hadoop100:9092 --list
    
  3. 创建topic first

    由于只有一台虚拟机,所以就省略了设置分区数和设置分区副本

    [luomuchen@hadoop100 kafka_2.12-3.2.0]$ bin/kafka-topics.sh --bootstrap-server hadoop100:9092 --create --topic first
    
  4. 查看 first 主题的详情

    [luomuchen@hadoop100 kafka_2.12-3.2.0]$ bin/kafka-topics.sh --bootstrap-server hadoop100:9092 --describe --topic first
    
  5. 修改分区数(注意:分区数只能增加,不能减少)

    [atguigu@hadoop102 kafka]$ bin/kafka-topics.sh --bootstrap-server 
    hadoop102:9092 --alter --topic first --partitions 3
    
  6. 再次查看 first 主题的详情

    [atguigu@hadoop102 kafka]$ bin/kafka-topics.sh --bootstrap-server 
    hadoop102:9092 --describe --topic first
    

3.2 生产者命令行操作

  1. 生产者命令参数

    image-20220616224201721

  2. 发送消息

    [luomuchen@hadoop100 kafka_2.12-3.2.0]$ bin/kafka-console-producer.sh --bootstrap-server hadoop100:9092 --topic first
    >hellow^H ^H^H^H^H^H^H^H^H^H^H
    >jhe^H^H^H
    >je
    >helloworld
    >luop^Hmuchen
    #alt+z停止 ^H是回退标志
    

3.3 消费者命令行操作

  1. 查看操作消费者命令参数

    image-20220616224201721

    image-20220616224201721

  2. 消费消息

    1. 消费 first 主题中的数据。

      [atguigu@hadoop102 kafka]$ bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic first
      #一台主机暂时无法测试这个
      
    2. 把主题中所有的数据都读取出来(包括历史数据)。

      [luomuchen@hadoop100 kafka_2.12-3.2.0]$ bin/kafka-console-consumer.sh --bootstrap-server hadoop100:9092 --from-beginning --topic first
      jhelo 
      je
      helloworld
      luomuchen
      

4. kafka和java结合

注:项目采用了springboot框架,因此结合会简单一些。
注意关闭防火墙,注意关闭防火墙,注意关闭防火墙!!!

  1. yml配置文件
    spring:
      kafka:
      #kafka集群
      bootstrap-servers: hadoop100:9092
      producer:
        value-serializer: org.apache.kafka.common.serialization.StringSerializer
        key-serializer: org.apache.kafka.common.serialization.StringSerializer
      consumer:
        key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
        value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
        group-id: 1
    
  2. pom.xml引入kafka的包
    <dependency>
      <groupId>org.springframework.kafka</groupId>
      <artifactId>spring-kafka</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.kafka</groupId>
      <artifactId>kafka-clients</artifactId>
      <version>2.6.0</version>
    </dependency>
    
  3. kafka生产
    使用kakfa包中自带的KafkaTemplate类来进行kakfa的写入,也就是kafka的生产者
    @Service("kafkaService")
     public class KafkaServiceImpl implements KafkaService {
         @Autowired
         private KafkaTemplate<String, String> kafkaTemplate;
         @Override
         public void kafkaSend(String topic, String msg) {
             kafkaTemplate.send(topic, msg);
         }
     }
    
  4. kafka消费
    使用@KafkaListener(topics = "") 注解,可以写入一个或多个topic进行消费
    @KafkaListener(topics = "goodMsg")
    public void goodMsgTopic(String msg){
      log.info("接收到一条不含敏感词的短信:" + msg);
    }
    
    也可以不使用注解,使用其他方式如直接配置来进行kafka的消费,这种方法的优势在于可以自行配置kafka,也可以在kafka监听前进行一些操作,缺点在于太过于繁琐。如下面这个例子,是一个敏感词过滤的kafka消费,由于topic是存在数据库中的,因此需要在消费时将数据库中的topic取出。
    @Order(1)
    @Service
    @Slf4j
    public class KafkaConsumers extends ServiceImpl<TopicMapper, Topic> implements InitializingBean {
        private static KafkaConsumer<String, String> consumer;
        private List<String> topicList;
        @Autowired
        private WordService wordService;
        @Autowired
        private KafkaService kafkaService;
        private GfaUtil gfaUtil = new GfaUtil();
        @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;
    
        @Autowired
        private static TopicService topicService;
        public List<String> getTopicList(){
            try {
                List<String> list = new ArrayList<>();
                List<Topic> list2 = baseMapper.selectList(null);
                for (Topic topic : list2) {
                    list.add(topic.getTopicValue());
                }
                return list;
            }
            catch (Exception e){
                log.error(e.toString());
            }
            return null;
        }
        public KafkaConsumer<String, String> getInitConsumer(List<String> topicList) {
            //配置信息
            Properties props = new Properties();
    
            //kafka服务器地址
            props.put("bootstrap.servers", bootstrapServers);
            //必须指定消费者组
            props.put("group.id", groupId);
            //设置数据key和value的序列化处理类
            props.put("key.deserializer", keyDeserializer);
            props.put("value.deserializer", valueDeserializer);
            //创建消息者实例
            KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
            //订阅topic的消息
            consumer.subscribe(topicList);
            return consumer;
        }
        @Override
        public void afterPropertiesSet() throws Exception {
            topicList = getTopicList();
            if (topicList != null && !topicList.isEmpty()) {
                consumer = getInitConsumer(topicList);
                // 开启一个消费者线程
                new Thread(() -> {
                    while (true) {
                        ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000));
                        for (ConsumerRecord<String, String> record : records) {
                            String msg = (String) record.value();
                            if (record.topic().equals("input")){
                                //如果字典树未生成,需要先生成字典树
    
                                if(DictionaryConfig.DICTIONARY_MAP == null){
                                    List<Word> wordList = wordService.getAllWord();
                                    Set<String> wordSet = new HashSet<>();
                                    for (Word word : wordList) {
                                        wordSet.add(word.getWord());
                                        DictionaryConfig.WORD_MAP.put(word.getWord(), word.getId());
                                    }
                                    DictionaryConfig.DICTIONARY_MAP = gfaUtil.setDictionary(wordSet);
                                }
                                if (!gfaUtil.check(msg, DictionaryConfig.DICTIONARY_MAP)){
                                    //log.info(msg + "包含敏感词");
                                    kafkaService.kafkaSend("badMsg", msg);
                                }
                                else{
                                    kafkaService.kafkaSend("goodMsg", msg);
                                }
                            }
                            else if(record.topic().equals("badMsg")){
                                log.info("接收到一条含有敏感词的短信:" + msg);
                            }
                            else{
                                log.info("接收到一条不含敏感词的短信:" + msg);
                            }
                        }
                    }
                }).start();
            }
        }
    }
    
posted @ 2022-06-22 10:17  洛沐辰  阅读(50)  评论(0编辑  收藏  举报