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或用@KafkaListener的autoStartup |
| 序列化异常 | 信任包未配置 | 设置spring.json.trusted.packages |
| 版本冲突 | kafka-clients与broker不匹配 | 参考兼容性矩阵升级客户端或broker |
七、总结
通过Spring Kafka,可以用少量注解和配置,就将Kafka的强大消息能力集成到Spring Boot应用中。本文涵盖了从基础配置、发送接收、事务保证到生产级错误处理的全流程。