springboot kafka消息消费学习 @KafkaListener 使用

kafka 配置类

用途:定义使用的基本 kafka 配置,以及定义Bean

下面文件是读取本地 spring 的标准配置文件的类,用于一般属性获取等操作

java 复制代码
import lombok.Data;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.config.KafkaListenerContainerFactory;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
import org.springframework.kafka.listener.ContainerProperties;
import org.springframework.stereotype.Component;

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

@Component
@ConfigurationProperties(prefix = "my.kafka")
@Data
public class MyTaskKafkaProperties {

    /**r
     * kafka地址
     */
    private String serverUrl;

    /**
     * groupId
     */
    private String groupId;

    /**
     * topic
     */
    private String topic;

    private boolean enableAutoCommit;

    private String autoOffsetReset;

    @Bean
    KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<Integer, String>> kafkaTwoContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<Integer, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        factory.setConcurrency(6);
        factory.getContainerProperties().setPollTimeout(6000);
        factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
        return factory;
    }

    private ConsumerFactory<Integer, String> consumerFactory() {
        return new DefaultKafkaConsumerFactory<>(consumerConfigs());
    }

    private Map<String, Object> consumerConfigs() {
        Map<String, Object> props = new HashMap<>();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, serverUrl);
        props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, enableAutoCommit);
        props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, autoOffsetReset);
        return props;
    }
}

@Data 为其他用于控制get set 方法的,与 此处配置不是强关联,可以没有

实际 kafka 监听消费

java 复制代码
import com.dtdream.dthink.dtalent.dmall.openplat.service.opendata.OpenDataService;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.kafka.support.KafkaHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Slf4j
@ConditionalOnProperty(name = "my.kafka.enable", havingValue = "true")
@Component
public class MyTaskConsumer {
    @Autowired
    private XxxxxService xxxxxService;

    @KafkaListener(topics = "${my.kafka.topic}", groupId = "${my.kafka.groupId}",
            containerFactory = "kafkaTwoContainerFactory")
    public void dxpTaskEnd(ConsumerRecord<String, String> record, Acknowledgment ack,
                           @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
        consume(record, ack, topic, msg -> xxxxxService.xxxxxxx(msg));
    }

    private void consume(ConsumerRecord<String, String> record, Acknowledgment ack, String topic,
                         java.util.function.Consumer<String> consumer) {
        Optional<String> optional = Optional.ofNullable(record.value());
        if (!optional.isPresent()) {
            log.warn("kafka收到消息 但为空,record:{}", record);
            return;
        }
        String msg = optional.get();
        log.info("kafka收到消息  开始消费 topic:{},msg:{}", topic, msg);
        try {
            consumer.accept(msg);
            // 上面方法执行成功后手动提交
            ack.acknowledge();
            log.info("kafka收到消息消费成功 topic:{},msg:{}", topic, msg);
        } catch (Exception e) {
            log.error("kafka消费消息失败 topic:{},msg:{}", topic, msg, e);
        }
    }
}

@ConditionalOnProperty spring boot 用于判断当前类是否加载的条件

XxxxxService: 为我们的业务服务层,用于消费消息

相关推荐
递归尽头是星辰12 小时前
Spring Boot 配置排除失效深度解析:时序与机制核心
spring boot·自动配置·bean 加载·exclude失效·组件扫描
小锋java123413 小时前
SpringBoot 4 + Spring Security 7 + Vue3 前后端分离项目设计最佳实践
java·vue.js·spring boot
一 乐13 小时前
校园线上招聘|基于springboot + vue校园线上招聘系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·校园线上招聘系统
不懂的浪漫13 小时前
mqtt-plus 架构解析(四):MqttMessageInterceptor 的扩展点设计
java·spring boot·物联网·mqtt
宠友信息14 小时前
一套基于uniapp+springboot完整社区系统是如何实现的?友猫社区源码级功能解析
java·spring boot·后端·微服务·微信·uni-app
阿丰资源15 小时前
SpringBoot+MySQL+MyBatis-Plus+Vue前后端分离仓库管理系统 (附资料)
spring boot·mysql·mybatis
小信丶15 小时前
Spring Cloud Stream EnableBinding注解详解:定义、应用场景与示例代码
java·spring boot·后端·spring
s1mple“”15 小时前
互联网大厂Java面试实录:谢飞机的AIGC求职之旅 - JVM并发编程到Spring Cloud微服务
spring boot·aigc·微服务架构·java面试·分布式系统·rag技术·redis数据库
ffqws_16 小时前
Spring Boot入门:通过简单的注册功能串联Controller,Service,Mapper。(含有数据库建立,连接,及一些关键注解的讲解)
数据库·spring boot·后端
YDS82916 小时前
大营销平台 —— 抽奖前置规则过滤
java·spring boot·ddd