kafka搭建过程和配置
搭建过程:
首先,需要在pom.xml文件中添加Kafka依赖:
```xml <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> <version>2.5.7.RELEASE</version> </dependency> ```
接下来,需要在application.properties文件中配置Kafka相关属性:
```properties spring.kafka.bootstrap-servers=localhost:9092 spring.kafka.consumer.group-id=my-group spring.kafka.consumer.auto-offset-reset=earliest spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer ```
然后,可以创建一个KafkaProducerConfig类来配置生产者:
```java @Configuration public class KafkaProducerConfig { @Value("${spring.kafka.bootstrap-servers}") private String bootstrapServers; @Bean public ProducerFactory<String, String> producerFactory() { Map<String, Object> configProps = new HashMap<>(); configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); return new DefaultKafkaProducerFactory<>(configProps); } @Bean public KafkaTemplate<String, String> kafkaTemplate() { return new KafkaTemplate<>(producerFactory()); } } ```
接着,可以创建一个KafkaConsumerConfig类来配置消费者:
```java @Configuration @EnableKafka public class KafkaConsumerConfig { @Value("${spring.kafka.bootstrap-servers}") private String bootstrapServers; @Value("${spring.kafka.consumer.group-id}") private String groupId; @Bean public ConsumerFactory<String, String> consumerFactory() { Map<String, Object> props = new HashMap<>(); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); 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); return new DefaultKafkaConsumerFactory<>(props); } @Bean public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() { ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>(); factory.setConsumerFactory(consumerFactory()); return factory; } } ```
最后,可以创建一个KafkaProducer类来发送消息:
```java @Service public class KafkaProducer { @Autowired private KafkaTemplate<String, String> kafkaTemplate; public void sendMessage(String topic, String message) { kafkaTemplate.send(topic, message); } } ```
还可以创建一个KafkaConsumer类来接收消息:
```java @Service public class KafkaConsumer { @KafkaListener(topics = "my-topic", groupId = "my-group") public void listen(String message) { System.out.println("Received message: " + message); } } ```
这样就可以在业务中使用Kafka了。例如,可以在Controller中调用KafkaProducer来发送消息:
```java @RestController public class MyController { @Autowired private KafkaProducer kafkaProducer; @PostMapping("/send") public void sendMessage(@RequestParam String message) { kafkaProducer.sendMessage("my-topic", message); } } ```
当有消息发送到"my-topic"主题时,KafkaConsumer中的listen方法就会被调用,接收并处理消息。
配置:
```properties # Kafka配置 spring.kafka.bootstrap-servers=localhost:9092 spring.kafka.consumer.group-id=my-group spring.kafka.consumer.auto-offset-reset=earliest spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
1.auto-offset-reset
在Kafka中,auto-offset-reset是一个重要的配置参数,它用于指定当消费者订阅一个主题时,如果没有可用的偏移量(offset)或偏移量无效时,应该采取什么行动。 具体来说,auto-offset-reset有三个可选值: a. earliest:表示消费者将从最早的可用偏移量开始消费消息。如果消费者组之前没有消费过该主题,则从最早的消息开始消费;如果消费者组之前已经消费过该主题,则从上一次消费的最后一个偏移量开始消费。 b. latest:表示消费者将从最新的可用偏移量开始消费消息。如果消费者组之前没有消费过该主题,则从最新的消息开始消费;如果消费者组之前已经消费过该主题,则从上一次消费的最后一个偏移量开始消费。 c. none:表示如果没有可用的偏移量,则抛出异常。这种情况下,消费者必须手动指定偏移量。 auto-offset-reset的作用是确保消费者能够正确地从指定的偏移量开始消费消息,从而避免数据丢失或重复消费的问题。在实际应用中,根据具体的业务需求和数据处理逻辑,选择合适的auto-offset-reset值非常重要。
2.配置详细内容
在使用Spring Boot搭建Kafka时,需要在application.yml文件中进行配置。下面是一些常见的配置项及其含义:
```yaml spring: kafka: bootstrap-servers: localhost:9092 # Kafka集群地址 consumer: group-id: my-group # 消费者组ID auto-offset-reset: earliest # 自动重置偏移量 enable-auto-commit: true # 是否自动提交偏移量 key-deserializer: org.apache.kafka.common.serialization.StringDeserializer # key反序列化器 value-deserializer: org.apache.kafka.common.serialization.StringDeserializer # value反序列化器 producer: acks: all # 生产者确认模式 retries: 0 # 生产者重试次数 batch-size: 16384 # 生产者批量发送大小 linger-ms: 1 # 生产者发送延迟时间 buffer-memory: 33554432 # 生产者缓存大小 ```
- `bootstrap-servers`:Kafka集群地址,可以配置多个,用逗号分隔。
- `consumer.group-id`:消费者组ID,同一个组内的消费者共同消费一个主题的消息。
- `consumer.auto-offset-reset`:自动重置偏移量,当消费者第一次加入消费组或者偏移量无效时,从哪个位置开始消费。可选值为`earliest`(从最早的消息开始消费)和`latest`(从最新的消息开始消费)。
- `consumer.enable-auto-commit`:是否自动提交偏移量,如果开启自动提交,消费者会在消费完一批消息后自动提交偏移量,否则需要手动提交。
- `consumer.key-deserializer`和`consumer.value-deserializer`:key和value的反序列化器,用于将Kafka中的二进制数据反序列化为Java对象。
- `producer.acks`:生产者确认模式,可选值为`all`(所有副本都确认后才算发送成功)、`1`(只要有一个副本确认就算发送成功)和`0`(不等待任何确认,直接发送)。
- `producer.retries`:生产者重试次数,当发送消息失败时,生产者会自动重试,最多重试次数由该配置项指定。
- `producer.batch-size`:生产者批量发送大小,当生产者积累到一定数量的消息后,会批量发送到Kafka。
- `producer.linger-ms`:生产者发送延迟时间,当生产者积累到一定数量的消息后,如果在指定的时间内没有达到批量发送大小,也会发送消息。
- `producer.buffer-memory`:生产者缓存大小,用于缓存待发送的消息。如果缓存满了,生产者会阻塞等待缓存空间释放。
3.设置监听分区
在使用 `@KafkaListener` 注解时,可以通过 `partition` 属性来指定消费者监听的分区。例如:
```java @KafkaListener(topicPartitions = @TopicPartition(topic = "myTopic", partitions = {"0", "1"})) public void listenToPartition(@Payload String message) { // 处理消息 } ```
上面的代码中,`@KafkaListener` 注解监听了 `myTopic` 主题的 `0` 和 `1` 分区。如果需要监听多个分区,可以在 `partitions` 属性中指定多个分区编号。如果需要监听所有分区,则可以省略 `partitions` 属性。
除了使用 `@KafkaListener` 注解,还可以通过 `KafkaListenerEndpointRegistry` 和 `KafkaMessageListenerContainer` 等类来手动设置分区。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理