学习日记--SpringBoot整合kafka(zookeeper)--服务器配置--后端实现

1.创建zookeeper容器(直接创建容器时如果没有镜像会自动拉取最新版本的镜像)

docker run -d --name zookeeper -p 2181:2181 -v /etc/localtime:/etc/localtime wurstmeister/zookeeper

2.创建kafka容器

## KAFKA_ZOOKEEPER_CONNECT 需要修改成zookeeper所在容器IP,容器之间是可以通过IP访问的
docker run -d --name kafka -p 9092:9092 -e KAFKA_BROKER_ID=1 -e KAFKA_ZOOKEEPER_CONNECT=172.17.0.9:2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://47.100.215.27:9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 -v /etc/localtime:/etc/localtime -t wurstmeister/kafka:latest

参数

-e KAFKA_BROKER_ID=0 //在kafka集群中,每个kafka都有一个BROKER_ID来区分自己

-e KAFKA_ZOOKEEPER_CONNECT=172.17.0.9:2181//kafka 配置zookeeper管理kafka的路径 //zookeeper地址

-e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://47.100.215.27:9092 //把kafka的地址端口注册给zookeeper

-e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 //配置kafka的监听端口

-v /etc/localtime:/etc/localtime //容器时间同步虚拟机的时间

zookeeper容器的ip地址使用docker inspect [容器id] 查看如下图

tips:创建过程中遇到的问题时记得用docker logs查看容器日志,如果free -h查看的内存不足可以通过增加swap空间解决

 三种创建方式

·作用于内网

## KAFKA_ZOOKEEPER_CONNECT 需要修改成zookeeper所在容器IP(docker inspect查看),容器之间是可以通过IP访问的,但是不能填写成虚拟IP
docker run -d --name kafka -p 9092:9092 -e KAFKA_BROKER_ID=1 -e KAFKA_ZOOKEEPER_CONNECT=172.17.0.9:2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 -v /etc/localtime:/etc/localtime -t wurstmeister/kafka:latest

·作用于外网(一般不存在)

docker run -d --name kafka -p 9092:9092 -e KAFKA_BROKER_ID=1 -e KAFKA_ZOOKEEPER_CONNECT=(服务器外网IP):2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://(服务器外网IP):9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 -v /etc/localtime:/etc/localtime -t wurstmeister/kafka:latest

# 2.然后再本机的hosts文件中中添加  服务器的外网ip和对应的服务器名字,例如:(服务器外网IP)   VM-24-5-centos

# 3.java代码中直接使用代码: 
# // 设置配置文件的方式
Properties properties = new Properties();
# // 设置链接的主服务器
# // 连接当前远程的服务器出现了url错误,需要进行修改,切记加上9092
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "VM-24-5-centos:9092");

 

·整合SpringBoot

docker run  -d --name kafka -p 9092:9092  -e KAFKA_BROKER_ID=0 -e KAFKA_ZOOKEEPER_CONNECT=(服务器内网IP):2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://(服务器外网IP):9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 -t wurstmeister/kafka:latest

内网ip和外网ip可以去自己的云服务器看

 

 3.创建好后可以进入容器测试kafka

 

 4.后端代码

 yml配置

  kafka:
    bootstrap-servers: kafka服务器ip:端口

    producer: # producer 生产者
      retries: 0 # 重试次数
      acks: 1 # 应答级别:多少个分区副本备份完成时向生产者发送ack确认(可选0、1、all/-1)
      batch-size: 16384 # 批量大小
      buffer-memory: 33554432 # 生产端缓冲区大小
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      #      value-serializer: com.itheima.demo.config.MySerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer

    consumer: # consumer消费者
      group-id: defaultConsumerGroup # 默认的消费组ID
      enable-auto-commit: true # 是否自动提交offset
      auto-commit-interval-ms: 1000 # 提交offset延时(接收到消息后多久提交offset)

      # earliest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费
      # latest:当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据
      # none:topic各分区都存在已提交的offset时,从offset后开始消费;只要有一个分区不存在已提交的offset,则抛出异常
      auto-offset-reset: latest
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      #      value-deserializer: com.itheima.demo.config.MyDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer

生产者(一般是在控制层或者业务层调用)

package com.example.demo.component;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;

/**
 * @Date 2022/7/7 15:07
 * @ClassName kafkaProducer
 * @Description ToDo
 * @Author LongX
 **/
@Component
public class KafkaProducer {
    /**
     * KafkaTemplate泛型类型跟消费者ConsumerRecord的泛型类型保持一致
     */
    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;
    /**
     * 发送消息
     */
    public void sendMessage() {
        try{
            //生产消息
            String message = "hello ! 测试kafka ";
            ListenableFuture<SendResult<String, String>> listenableFuture = kafkaTemplate.send("hello","hello", message);
            listenableFuture.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
                @Override
                public void onSuccess(SendResult<String, String> result) {
                    System.out.println("sendMessage success");
                }
                @Override
                public void onFailure(Throwable ex) {
                    System.out.println("sendMessage error");
                }
            });
        }catch (Exception e){
            System.out.println("sendMessage exception");
        }
    }
}

消费者(监听某些topic就可以了)

package com.example.demo.component;

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;

/**
 * @Date 2022/7/7 15:36
 * @ClassName TopicComponent
 * @Description ToDo
 * @Author LongX
 **/
@Component
public class TopicComponent {

    @KafkaListener(topics = {"hello","hello2"})
    public void handMessage(ConsumerRecord<String, String> record){
        String topic = record.topic();
        String msg = record.value();
        System.out.println("消费者接受消息:topic-->"+topic+",msg->>"+msg);
    }
}

生产调用实例(控制层)

package com.example.demo.controller;


import com.example.demo.component.KafkaProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Date 2022/7/7 15:30
 * @ClassName KafkaProController
 * @Description ToDo
 * @Author LongX
 **/
@RestController
public class KafkaProController {
    @Autowired
    private KafkaProducer kafkaProducer;
    @RequestMapping("/hello")

    public String hello(){
        System.out.println("------->测试生产者发送消息");
        kafkaProducer.sendMessage();
        return "kafka消息已发送.";
    }
}

 

posted @ 2022-07-06 22:11  忙碌了一整天的L师傅  阅读(911)  评论(0编辑  收藏  举报