SpringBoot集成kafka配置使用(一)

目录

1、pom文件的引入

2、kafkaConfig

3、消息的生产者(KafkaSender)

4、消息的消费者(KafkaReceiver)

5、yml配置文件

6、使用(so easy)


项目中原版使用的是rocketmq,由于客户那边用的是kafka。先把中间件更换长kafka,步入正题:

1、pom文件的引入

        
        
            org.springframework.kafka
            spring-kafka
        

2、kafkaConfig

package com.wlsj.gxdc.config;

import org.springframework.boot.autoconfigure.kafka.ConcurrentKafkaListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.listener.DeadLetterPublishingRecoverer;
import org.springframework.kafka.listener.SeekToCurrentErrorHandler;
import org.springframework.util.backoff.FixedBackOff;

@Configuration
public class KafkaConfig {

    @Bean
    public ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory(
            ConcurrentKafkaListenerContainerFactoryConfigurer configurer,
            ConsumerFactory kafkaConsumerFactory,
            KafkaTemplate template) {
        ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>();
        configurer.configure(factory, kafkaConsumerFactory);
        factory.setErrorHandler(new SeekToCurrentErrorHandler(
                new DeadLetterPublishingRecoverer(template), new FixedBackOff(0L, 2))); // dead-letter after 3 tries
        return factory;
    }


}

3、消息的生产者(KafkaSender)

package com.wlsj.gxdc.kafka;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class KafkaSender {

    @Autowired
    private KafkaTemplate kafkaTemplate;

    //异步发送消息方法
    public void sendAsynchronize(String topic, String message) {
        kafkaTemplate.send(topic, message);
    }

    //同步发送消息方法
    public void sendSynchronize(String topic, String message) throws Exception {
        kafkaTemplate.send(topic, message).get();

    }

}

4、消息的消费者(KafkaReceiver)

package com.wlsj.gxdc.kafka;

import com.alibaba.fastjson.JSONObject;
import com.wlsj.gxdc.entity.Bicycle;
import com.wlsj.gxdc.entity.BicyclePosition;
import com.wlsj.gxdc.service.IBicyclePositionService;
import com.wlsj.gxdc.service.IBicycleService;
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.stereotype.Component;

import java.util.Optional;

@Slf4j
@Component
public class KafkaReceiver {
    @Autowired
    private IBicyclePositionService bicyclePositionService;
    @Autowired
    private IBicycleService bicycleService;

    @KafkaListener(topics = {"${kafka.topic.bicycle_topic}"})
    public void listen1(ConsumerRecord record) {
        Optional kafkaMessage = Optional.ofNullable(record.value());
        if (kafkaMessage.isPresent()) {
            Object message = kafkaMessage.get();
            JSONObject jsonObject = JSONObject.parseObject(message.toString());
            if (null != jsonObject) {
                Bicycle bicycle = JSONObject.toJavaObject(jsonObject, Bicycle.class);
                try {
                    bicycleService.save(bicycle);
                } catch (Exception e) {
                    log.info(e.getMessage());
                }
            }
            log.info("kafka车辆备案消息:{}", message);
            log.info("----------------- record =" + record);
        }

    }

    @KafkaListener(topics = {"${kafka.topic.bicycle_position_topic}"})
    public void listen2(ConsumerRecord record) {
        Optional kafkaMessage = Optional.ofNullable(record.value());
        if (kafkaMessage.isPresent()) {
            Object message = kafkaMessage.get();
            JSONObject jsonObject = JSONObject.parseObject(message.toString());
            if (null != jsonObject) {
                BicyclePosition bicyclePosition = JSONObject.toJavaObject(jsonObject, BicyclePosition.class);
                log.info("=======================bicyclePosition =" + bicyclePosition);
                try {
                    bicyclePositionService.save(bicyclePosition);
                    bicyclePositionService.updatePositionByBicycleId(bicyclePosition);
                } catch (Exception e) {
                    log.info(e.getMessage());
                }
            }
            log.info("kafka车辆位置消息:{}", message);
        }

    }
}

5、yml配置文件

server:
  undertow:
    io-threads: 6
    worker-threads: 48
    buffer-size: 1024
    buffers-per-region: 1024
    direct-buffers: true
  port: ${PORT:8080}
  #  tomcat:
  #    max-swallow-size: -1
  servlet:
    context-path: /${spring.application.name}
    compression:
      enabled: true
      mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*

management:
  endpoints:
    web:
      exposure:
        include: metrics,httptrace
spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB
  kafka:
    bootstrap-servers: 172.16.251.70:6667,172.16.251.77:6667,172.16.251.46:6667,172.16.251.66:6667, 172.16.251.87:6667, 172.16.251.85:6667, 172.16.251.73:6667, 172.16.251.61:6667
    producer:
      # 发生错误后,消息重发的次数。
      retries: 0
      #当有多个消息需要被发送到同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算。
      batch-size: 16384
      # 设置生产者内存缓冲区的大小。
      buffer-memory: 33554432
      # 键的序列化方式
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      # 值的序列化方式
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
      # acks=0 : 生产者在成功写入消息之前不会等待任何来自服务器的响应。
      # acks=1 : 只要集群的首领节点收到消息,生产者就会收到一个来自服务器成功响应。
      # acks=all :只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应。
      acks: 1
      properties:
        sasl.mechanism: PLAIN
        security.protocol: SASL_PLAINTEXT
        sasl.jaas.config: org.apache.kafka.common.security.scram.ScramLoginModule required username="share_bikes" password="9cfb8e5b";
    consumer:
      # 自动提交的时间间隔 在spring boot 2.X 版本中这里采用的是值的类型为Duration 需要符合特定的格式,如1S,1M,2H,5D
      auto-commit-interval: 1S
      # 该属性指定了消费者在读取一个没有偏移量的分区或者偏移量无效的情况下该作何处理:
      # latest(默认值)在偏移量无效的情况下,消费者将从最新的记录开始读取数据(在消费者启动之后生成的记录)
      # earliest :在偏移量无效的情况下,消费者将从起始位置读取分区的记录
      auto-offset-reset: earliest
      # 是否自动提交偏移量,默认值是true,为了避免出现重复数据和数据丢失,可以把它设置为false,然后手动提交偏移量
      enable-auto-commit: false
      group-id: ${spring.profiles.active}-group
      # 键的反序列化方式
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      # 值的反序列化方式
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      properties:
        sasl.mechanism: PLAIN
        security.protocol: SASL_PLAINTEXT
        sasl.jaas.config: org.apache.kafka.common.security.scram.ScramLoginModule required username="share_bikes" password="9cfb8e5b";
    listener:
      # 在侦听器容器中运行的线程数。
      concurrency: 5
      #listner负责ack,每调用一次,就立即commit
      ack-mode: manual_immediate
      missing-topics-fatal: false
kafka:
  topic:
    bicycle_topic: bikes_record
    bicycle_position_topic: share_bikes

6、使用(so easy)

@Autowired
KafkaSender kafkaSender;
kafkaSender.sendAsynchronize(kafkaTopicPo.getBicyclePositionTopic(), JSON.toJSONString(bicyclePosition));

你可能感兴趣的:(java,java,后端)