Spring Boot集成Kafka完整版

Spring Boot集成Kafka完整版

一、为什么选择Spring Boot + Kafka?

Spring Boot与Spring Kafka的整合,让开发者能够以声明式、低代码的方式实现生产者和消费者,无需关注底层连接和线程管理。

Spring Kafka提供:

  • KafkaTemplate ------ 像JdbcTemplate一样发送消息
  • @KafkaListener ------ 注解驱动、异步消费
  • KafkaTransactionManager ------ 实现精确一次(Exactly-Once)语义

二、版本兼容性说明

根据Spring官方文档,下表为推荐版本组合(以Spring Boot 3.x为例):

Spring Boot Spring Kafka kafka-clients
3.4.x 4.0.x 4.1.2
3.3.x 3.3.x 3.8.0 ~ 3.9.0
3.2.x 3.2.x 3.7.0
3.1.x 3.1.x 3.6.0

客户端版本必须与Kafka broker兼容。例如kafka-clients 4.x可与broker 3.x及更高版本通信,但建议使用官方Kafka兼容性矩阵

三、实战:从零搭建Kafka消息系统

1. 初始化Spring Boot项目

通过 Spring Initializr 添加依赖:

  • Spring Web (便于测试REST触发消息)
  • Spring for Apache Kafka

或在pom.xml中手动添加:

xml 复制代码
<dependency>
    <groupId>org.springframework.kafka</groupId>
    <artifactId>spring-kafka</artifactId>
</dependency>

2. 配置Kafka连接

编辑application.yml

yaml 复制代码
spring:
  kafka:
    bootstrap-servers: localhost:9092
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
    consumer:
      group-id: my-group
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
      properties:
        spring.json.trusted.packages: "*"

3. 创建消息实体

java 复制代码
public class OrderEvent {
    private String orderId;
    private double amount;
    // 构造函数、getter/setter ...
}

4. 生产者:使用KafkaTemplate发送消息

java 复制代码
@Service
public class OrderProducer {
    @Autowired
    private KafkaTemplate<String, OrderEvent> kafkaTemplate;

    public void sendOrder(OrderEvent order) {
        kafkaTemplate.send("order-topic", order.getOrderId(), order);
        System.out.println("订单已发送: " + order.getOrderId());
    }
}

5. 消费者:使用@KafkaListener接收消息

java 复制代码
@Component
public class OrderConsumer {
    @KafkaListener(topics = "order-topic", groupId = "order-processor")
    public void processOrder(OrderEvent order) {
        System.out.println("处理订单: " + order.getOrderId() + ", 金额: " + order.getAmount());
        // 执行业务逻辑...
    }
}

6. 在Controller中触发发送

java 复制代码
@RestController
public class OrderController {
    @Autowired
    private OrderProducer producer;

    @PostMapping("/order")
    public String createOrder(@RequestBody OrderEvent order) {
        producer.sendOrder(order);
        return "订单已提交";
    }
}

四、进阶配置与最佳实践

1. 事务性发送(Exactly-Once)

java 复制代码
@Transactional
public void sendWithTx(String topic, OrderEvent order) {
    kafkaTemplate.executeInTransaction(t -> {
        t.send(topic, order);
        // 若抛出异常则事务回滚
        return true;
    });
}

同时需配置spring.kafka.producer.transaction-id-prefix=tx-

2. 消费时的错误处理与重试

java 复制代码
@KafkaListener(topics = "order-topic")
@RetryableTopic(attempts = "4", backoff = @Backoff(delay = 2000))
public void processWithRetry(OrderEvent order) {
    // 可能失败的业务逻辑
}

需要额外依赖spring-retry

3. 配置多个消费者容器工厂

java 复制代码
@Bean
public ConcurrentKafkaListenerContainerFactory<String, String>
  customContainerFactory(ConsumerFactory<String, String> consumerFactory) {
    var factory = new ConcurrentKafkaListenerContainerFactory<String, String>();
    factory.setConsumerFactory(consumerFactory);
    factory.setConcurrency(3); // 并发数
    factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL);
    return factory;
}

然后在@KafkaListener中指定containerFactory

五、测试你的集成

推荐使用spring-kafka-test中的嵌入式Kafka:

xml 复制代码
<dependency>
    <groupId>org.springframework.kafka</groupId>
    <artifactId>spring-kafka-test</artifactId>
    <scope>test</scope>
</dependency>

编写测试用例时可用@EmbeddedKafka启动测试broker。

六、常见问题排查

现象 可能原因 解决方案
生产者超时 Broker不可达 检查bootstrap-servers及网络防火墙
消费不到消息 groupId不同或未提交offset 重置offset或用@KafkaListenerautoStartup
序列化异常 信任包未配置 设置spring.json.trusted.packages
版本冲突 kafka-clients与broker不匹配 参考兼容性矩阵升级客户端或broker

七、总结

通过Spring Kafka,可以用少量注解和配置,就将Kafka的强大消息能力集成到Spring Boot应用中。本文涵盖了从基础配置、发送接收、事务保证到生产级错误处理的全流程。

相关推荐
阿里云云原生4 小时前
告别冗长链路!Kafka × Table Bucket 实现开放表格式零 ETL 实时入湖
云原生·kafka
用户3169353811835 小时前
如何从零编写一个 Spring Boot Starter
spring boot
程序员晓琪1 天前
约定大于配置:基于 Java 包名自动生成 API 版本路由的最佳实践
java·spring boot·后端
Flittly1 天前
【AgentScope Java新手村系列】(11)中断与恢复
java·spring boot·spring
用户3521802454752 天前
🎆从 Prompt 到 Skill:让 Spring AI Agent 学会"装新技能"
人工智能·spring boot·ai编程
用户3521802454755 天前
当 Prompt 学会"热更新":Spring Boot × Nacos3 AI 实战
java·spring boot·ai编程
昵称为空C5 天前
手撸一个动态 SQL 执行引擎:不重启服务,在线增删改查任意数据库
spring boot·后端
霸道流氓气质6 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
于先生吖6 天前
SpringBoot对接大模型开发AI命理测算系统:八字排盘与AI解析接口源码全解
人工智能·spring boot·后端