基于SpringBoot3集成Kafka集群

1. build.gradle依赖引入

sh 复制代码
implementation 'org.springframework.kafka:spring-kafka:3.2.0'

2. 新增kafka-log.yml文件

在resource/config下面新增kafka-log.yml,配置主题与消费者组

yml 复制代码
# Kafka消费者群组
kafka:
  consumer:
    group:
      log-data: log-data-group
    topic:
      log-data: log-data-topic
    auto-startup: false

加载自定义yml文件

java 复制代码
@Configuration
public class YmlConfiguration {

    @Bean
    public PropertySourcesPlaceholderConfigurer properties() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
        yaml.setResources(new ClassPathResource[]{
                new ClassPathResource("config/kafka-log.yml")
        });
        configurer.setProperties(yaml.getObject());
        return configurer;
    }
}

3. application.yml文件配置

yml 复制代码
spring:
  kafka:
    bootstrap-servers: 192.168.0.81:9092,192.168.0.82:9092,192.168.0.83:9092
    producer:
      retries: 0
      batch-size: 16384
      buffer-memory: 254288
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
      auto-topic-creation:
        auto-create: true
      properties:
        linger.ms: 1
        session.timeout.ms: 15000
        sasl.mechanism: PLAIN
        security.protocol: SASL_PLAINTEXT
        sasl.jaas.config: org.apache.kafka.common.security.plain.PlainLoginModule required username="admin" password="your-password";
    consumer:
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      group-id: log-data-group
      auto-offset-reset: latest
      properties:
        session.timeout.ms: 15000
        sasl.mechanism: PLAIN
        security.protocol: SASL_PLAINTEXT
        sasl.jaas.config: org.apache.kafka.common.security.plain.PlainLoginModule required  username="admin"  password="your-password";
yml 复制代码
# 按需在不同环境配置值,如开发环境默认不启动
kafka:
  consumer:
    auto-startup: false

4. 生产者实现

java 复制代码
@Service
@Slf4j
public class KafkaProducer {

    private final KafkaTemplate<Integer, String> kafkaTemplate;

    public KafkaProducer(KafkaTemplate kafkaTemplate) {
        this.kafkaTemplate = kafkaTemplate;
    }

    public void sendMessage(String topic, String data) {
        CompletableFuture<SendResult<Integer, String>> future = kafkaTemplate.send(topic, data);
        future.whenComplete((sendResult, ex) -> {
            if (ex != null) {
                log.error("Kafka send message error = {}, topic = {}, data = {}", ex.getMessage(), topic, data);
            } else {
                // Handle the successful send
                System.out.println("Message sent successfully: " + sendResult);
            }
        });
    }
}

5. 消费者实现

java 复制代码
@Component
public class KafkaConsumerGroupManager {

    private KafkaAdmin kafkaAdmin;
    private ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory;

    public KafkaConsumerGroupManager(KafkaAdmin kafkaAdmin, ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory) {
        this.kafkaAdmin = kafkaAdmin;
        this.kafkaListenerContainerFactory = kafkaListenerContainerFactory;
    }

    public void ensureConsumerGroupExists(String groupId) {
        try {
            // 获取 AdminClient
            AdminClient adminClient = AdminClient.create(kafkaAdmin.getConfigurationProperties());

            // 检查消费者组是否存在
            ListConsumerGroupsResult listConsumerGroupsResult = adminClient.listConsumerGroups();
            Collection<org.apache.kafka.clients.admin.ConsumerGroupListing> consumerGroupListings = listConsumerGroupsResult.all().get();

            boolean groupExists = consumerGroupListings.stream()
                    .anyMatch(consumerGroupListing -> consumerGroupListing.groupId().equals(groupId));

            if (!groupExists) {
                // 如果不存在,则创建消费者组
                kafkaListenerContainerFactory.getContainerProperties().setGroupId(groupId);
            }
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException("Failed to check consumer group existence", e);
        }
    }
}
java 复制代码
@Service
@Slf4j
public class KafkaConsumer {

    private ElasticsearchOperations elasticsearchOperations206;

    public KafkaConsumer(ElasticsearchOperations elasticsearchOperations206) {
        this.elasticsearchOperations206 = elasticsearchOperations206;
    }

    /**
     * 日志数据消费
     *
     * @param message
     */
    @KafkaListener(topics = {"${kafka.consumer.topic.log-data}"}, groupId = "${kafka.consumer.group.log-data}", autoStartup = "${kafka.consumer.auto-startup}")
    public void consumer(String message) {
        this.bulkIndexJsonData(message);
    }

    public void bulkIndexJsonData(String jsonData) {
        List<IndexQuery> queries = new ArrayList<>();
        IndexQuery query = new IndexQuery();
        query.setSource(jsonData);
        query.setOpType(IndexQuery.OpType.INDEX);
        queries.add(query);
        elasticsearchOperations206.bulkIndex(queries, IndexCoordinates.of("log"));
    }
}

OK, 至此完毕。在某次集群宕机后,我们发现日志无法查询,经排查,是因为最初配置了auto-offset-reset: earliest 导致从头开始重新消费,幸好ES做了幂等性处理

相关推荐
明达智控技术16 小时前
告别停机内卷!热插拔远程IO,解锁工控运维新范式
分布式·物联网·自动化
漂着的圆木17 小时前
MCP 2026-07-28 长任务改造:别再用 HTTP 超时判断任务失败
分布式·架构·状态模式·ai agent
数智启示录1 天前
Apache Kafka Consumer 扩到 40 个仍不提速:Partition 上限锁死有效并行度 【Kafka合集】
数据库·经验分享·分布式·缓存·面试·kafka·apache
数智启示录1 天前
Apache Kafka 幂等 Producer 的边界:Exactly-Once 到了 MySQL 为什么失效 【Kafka合集】
数据库·经验分享·分布式·mysql·面试·kafka·apache
数智启示录1 天前
Apache Kafka 不只是消息队列:日志与 Offset 分离如何让事件可重放 【Kafka合集】
经验分享·分布式·面试·kafka·apache
数智启示录1 天前
Apache Kafka 同 Key 仍会乱序:从分区 Offset 到业务可见的四道边界 【Kafka 合集】
大数据·数据库·经验分享·分布式·面试·kafka·apache
BYSJMG1 天前
大数据毕业设计选题推荐:基于大数据的全球气温历史演变分析与可视化,用Hadoop+Spark处理
大数据·hadoop·分布式·信息可视化·spark·kmeans·课程设计
爱吃苹果的梨叔1 天前
AI 算力监控中心怎么建?分布式坐席 + 大屏联动 + 过程回放
人工智能·分布式·python
無a伟1 天前
RabbitMQ :与AMQP的关系、核心组件、交换机类型
分布式·rabbitmq
老周聊架构1 天前
Flink 连接器与生态:Kafka Offset 提交修复与 MySQL Binlog 延迟指标
mysql·flink·kafka