springBoot集成kafka

springBoot集成kafka实现(编写即用)

1.在springboot内添加相关依赖

org.springframework.kafka
spring-kafka
2.5.0.RELEASE

2.填写相关配置(相当于xml配置)
![在这里插入图片描述
3.相关代码实现(可替代.yml配置)代码与.yml二选一
/**

  • 通过代码自定义 Kafka 配置

  • */
    @Configuration
    public class KafkaConfig {

    @Value(“${spring.kafka.bootstrap-servers}”)
    private String bootstrapServers;

    /**

    • Kafka Producer 工厂类配置

    • */
      @Bean
      public ProducerFactory<String, String> producerFactory() {

      Map<String, Object> configs = new HashMap<>();
      //kafka地址
      configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
      //k序列化
      configs.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
      //v的序列化
      configs.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);

      return new DefaultKafkaProducerFactory<>(configs);
      }

    /**

    • Kafka Producer 客户端

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

    /**

    • Kafka Consumer 工厂类配置

    • */
      @Bean
      public ConsumerFactory<String, String> consumerFactory() {

      Map<String, Object> props = new HashMap<>();
      //从哪个消费者拿东西
      props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
      //最多拉取的数据
      props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, 50);
      props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
      props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);

      return new DefaultKafkaConsumerFactory<>(props);
      }

    /**

    • Kafka Consumer 监听器工厂类配置

    • */
      @Bean
      public ConcurrentKafkaListenerContainerFactory<String, String>
      kafkaListenerContainerFactory() {

      ConcurrentKafkaListenerContainerFactory<String, String> factory =
      new ConcurrentKafkaListenerContainerFactory<>();
      // 并发数就是一个消费者实例起几个线程
      factory.setConcurrency(3);
      factory.setConsumerFactory(consumerFactory());

      return factory;
      }
      }

4.定义KafKa生产者接受消息 KafkaProducer类
/**

  • kafka 生产者

  • */
    @Slf4j
    @Component
    public class KafkaProducer {

    private final KafkaTemplate<String, String> kafkaTemplate;

    public KafkaProducer(KafkaTemplate<String, String> kafkaTemplate) {
    this.kafkaTemplate = kafkaTemplate;
    }

    /**

    • 发送 kafka 消息

    • topic 消息队列 不能为空

    • value 消息 不能为空

    • key 区分队列分区 可以为空

    • */
      public void sendMessage(String key, String value, String topic) {

      if (StringUtils.isBlank(value) || StringUtils.isBlank(topic)) {
      throw new IllegalArgumentException(“value or topic is null or empty”);
      }

      ListenableFuture<SendResult<String, String>> future = StringUtils.isBlank(key) ?
      kafkaTemplate.send(topic, value) : kafkaTemplate.send(topic, key, value);

      // 异步回调的方式获取通知
      future.addCallback(
      success -> {
      assert null != success && null != success.getRecordMetadata();
      // 发送到 kafka 的 topic
      String _topic = success.getRecordMetadata().topic();
      // 消息发送到的分区
      int partition = success.getRecordMetadata().partition();
      // 消息在分区内的 offset
      long offset = success.getRecordMetadata().offset();

               log.info("send kafka message success: [{}], [{}], [{}]",
                       _topic, partition, offset);
           }, failure -> {
               log.error("send kafka message failure: [{}], [{}], [{}]",
                       key, value, topic);
           }
      

      );

      // 同步等待的方式获取通知
      try {
      // SendResult<String, String> sendResult = future.get();
      //5秒不返回信息 通知异常
      SendResult<String, String> sendResult = future.get(5, TimeUnit.SECONDS);

       // 发送到 kafka 的 topic
       String _topic = sendResult.getRecordMetadata().topic();
       // 消息发送到的分区
       int partition = sendResult.getRecordMetadata().partition();
       // 消息在分区内的 offset
       long offset = sendResult.getRecordMetadata().offset();
      
       log.info("send kafka message success: [{}], [{}], [{}]",
               _topic, partition, offset);
      

      } catch (Exception ex) {
      log.error(“send kafka message failure: [{}], [{}], [{}]”,
      key, value, topic);
      }
      }
      }
      5.创建kafka消费者 KafkaConsumer 类
      /**

  • Kafka 消费者

  • */
    @Slf4j
    @Component
    public class KafkaConsumer {

    private final ObjectMapper mapper;

    public KafkaConsumer(ObjectMapper mapper) {
    this.mapper = mapper;
    }

    /**

    • 监听 Kafka 消息并消费

    • */
      @KafkaListener(topics = {“qinyi-springboot”}, groupId = “qinyi-springboot-kafka”)
      public void listener01(ConsumerRecord<String, String> record) throws Exception {

      String key = record.key();
      String value = record.value();

      QinyiMessage kafkaMessage = mapper.readValue(value, QinyiMessage.class);
      log.info(“in listener01 consume kafka message: [{}], [{}]”,
      key, mapper.writeValueAsString(kafkaMessage));
      }

    /**

    • 监听 Kafka 消息并消费

    • */
      @KafkaListener(topics = {“qinyi-springboot”}, groupId = “qinyi-springboot-kafka-1”)
      public void listener02(ConsumerRecord<?, ?> record) throws Exception {

      Optional<?> _kafkaMessage = Optional.ofNullable(record.value());
      if (_kafkaMessage.isPresent()) {
      Object message = _kafkaMessage.get();
      QinyiMessage kafkaMessage = mapper.readValue(message.toString(),
      QinyiMessage.class);
      log.info(“in listener02 consume kafka message: [{}]”,
      mapper.writeValueAsString(kafkaMessage));
      }
      }
      }
      6.编写调用层类 KafkaController
      /**

  • SpringBoot 集成 kafka 发送消息

  • */
    @Slf4j
    @RestController
    @RequestMapping(“/kafka”)
    public class KafkaController {

    private final ObjectMapper mapper;
    private final KafkaProducer kafkaProducer;

    public KafkaController(ObjectMapper mapper, KafkaProducer kafkaProducer) {
    this.mapper = mapper;
    this.kafkaProducer = kafkaProducer;
    }

    /**

    • 发送 kafka 消息

    • */
      @GetMapping(“/send-message”)
      public void sendMessage(@RequestParam(required = false) String key,
      @RequestParam String topic) throws Exception {

      QinyiMessage message = new QinyiMessage(
      1,
      “Imooc-Study-Ecommerce”
      );
      //writeValueAsString 反序列化
      kafkaProducer.sendMessage(key, mapper.writeValueAsString(message), topic);
      }
      }

7.编写测试用例(提前要启动zk(默认端口:2181)+kafka(默认端口:9092))

kafka-send-message

GET http://127.0.0.1:8001/imooc-study-ecommerce-dev/kafka/send-message?key=qinyi&topic=qinyi-springboot
Content-Type: application/json

kafka-send-message

GET http://127.0.0.1:8001/imooc-study-ecommerce-dev/kafka/send-message?topic=qinyi-springboot
Content-Type: application/json

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值