Spring集成kafka

1. 引入依赖

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

2. yaml配置信息

java 复制代码
spring:
  kafka:
    bootstrap-servers: 127.0.0.1:9092
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
      retries: 3  # 重试次数
      batch-size: 16384 #批处理大小
      buffer-memory: 33554432 #缓冲区内存
      #acks: all # 最高可靠性
      #linger-ms: 50 # 等待时间
    consumer:
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      group-id: order-service-group # 消费者组
      auto-offset-reset: latest #消费者在启动时从哪里开始消费消息。可选值为"earliest"(从最早的消息开始消费)和"latest"(从最新的消息开始消费)
      enable-auto-commit: false #是否启用自动提交消费位移。如果设置为true,则消费者会自动提交消费位移,否则需要手动提交。
      # 提交offset延时(接收到消息后多久提交offset)
      #auto-commit-interval: 1000
      #properties:
        #session.timeout.ms: 60000
    # 监听器配置
    listener:
      ack-mode: manual_immediate # 手动提交
      concurrency: 3 # 并发消费者数
      #missing-topics-fatal: false
      #idle-event-interval: 60000  # 空闲事件间隔
      #log-container-config: false

3. 配置类

java 复制代码
@Configuration
@EnableConfigurationProperties({KafkaProperties.class})
@EnableKafka
@AllArgsConstructor
public class KafkaConfiguration {


	private final KafkaProperties kafkaProperties;

	@Bean
	public KafkaTemplate<String, String> kafkaTemplate() {
		return new KafkaTemplate<>(producerFactory());
	}

	@Bean
	public ProducerFactory<String, String> producerFactory() {
		return new DefaultKafkaProducerFactory<>(kafkaProperties.buildProducerProperties());
	}

	@Bean
	public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() {
		ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
		factory.setConsumerFactory(consumerFactory());
		factory.setConcurrency(3);
		// 配置批处理监听器,true表示启用
		factory.setBatchListener(true);
		// 配置的是消费者 轮询消息时的超时时间,单位是毫秒。轮询是 Kafka 消费者不断从 Kafka 分区拉取消息的过程。
		factory.getContainerProperties().setPollTimeout(3000);
		return factory;
	}

	@Bean
	public ConsumerFactory<String, String> consumerFactory() {
		return new DefaultKafkaConsumerFactory<>(kafkaProperties.buildConsumerProperties());
	}

	@Bean("ackContainerFactory")
	public ConcurrentKafkaListenerContainerFactory<String, String> ackContainerFactory() {
		ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
		factory.setConsumerFactory(consumerFactory());
		// 手动确认模式,消息处理完毕后立即确认消息已消费
		factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
		// 设置并发消费者线程数
		factory.setConcurrency(3);
		return factory;
	}

}

4. 生产者

  • 提供三种发送消息的方式,第一种不设置消息头部信息,另外两种可根据不同的方式设置消息头部信息
java 复制代码
@Slf4j
@RestController
@RequestMapping("/kafkaMsg")
public class MessageController {

    @Resource
    private KafkaTemplate<String, String> kafkaTemplate;

    @GetMapping( "/springSend")
    public void send(@RequestParam String message) {
         //发送消息
        ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send("highLoadEvent", message);
        // 监听回调
        future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
            @Override
            public void onSuccess(SendResult<String, String> result) {
                log.error("成功发送信息:{}......", result);
            }
            @Override
            public void onFailure(Throwable e) {
                log.info("发送消息失败......");
            }
        });
    }

    @GetMapping( "/springSendHeader1")
    public void sendHeader1(@RequestParam String message) {
        List<Header> headers = new ArrayList<>();
        // 添加自定义header
        headers.add(new RecordHeader("event", "TSP001".getBytes()));
        // 主题、分区、key、value、header
        ProducerRecord<String, String> record = new ProducerRecord<>("highLoadEvent1", 0, "", message, headers);
        log.info("sending message='{}' to topic='{}'", message, "highLoadEvent1");
        kafkaTemplate.send(record);
    }

    @GetMapping( "/springSendHeader2")
    public void sendHeader2(@RequestParam String message) {
        // 构建MessageBuilder对象须添加主题, 可添加自定义header
        Message<String> messageBuilder = MessageBuilder.withPayload(message)
                .setHeader(KafkaHeaders.TOPIC, "highLoadEvent2")
                //.setHeader(KafkaHeaders.MESSAGE_KEY, "999")
                //.setHeader(KafkaHeaders.PARTITION_ID, 0)
                .setHeader("event", "TSP002").build();
        log.info("sending messageBuilder='{}' to topic='{}'", message, "highLoadEvent2");
        kafkaTemplate.send(messageBuilder);
    }
}

5. 消费者

java 复制代码
@Slf4j
@Component
public class SpringKafkaListener {

    @KafkaListener(topics = "highLoadEvent1", groupId = "${commons.kafka.consumer.group-id}")
    public void handle(String message) {
        log.warn("接收到消息: {}", message);
    }

    @KafkaListener(topics = "highLoadEvent2",containerFactory = "ackContainerFactory")
    public void handleMessage(ConsumerRecord<String, String> record, Acknowledgment acknowledgment) {
        try {
            log.warn("正在接收消息: {}", record.value());
        } catch (Exception e) {
            log.error("处理消息时发生错误");
        } finally {
            acknowledgment.acknowledge();
        }
    }
}
相关推荐
洛豳枭薰13 小时前
消息队列关键问题描述
kafka·rabbitmq·rocketmq
lucky670714 小时前
Spring Boot集成Kafka:最佳实践与详细指南
spring boot·kafka·linq
Coder_Boy_14 小时前
基于Spring AI的分布式在线考试系统-事件处理架构实现方案
人工智能·spring boot·分布式·spring
7哥♡ۣۖᝰꫛꫀꪝۣℋ14 小时前
Spring-cloud\Eureka
java·spring·微服务·eureka
袁煦丞 cpolar内网穿透实验室15 小时前
远程调试内网 Kafka 不再求运维!cpolar 内网穿透实验室第 791 个成功挑战
运维·分布式·kafka·远程工作·内网穿透·cpolar
岁岁种桃花儿15 小时前
CentOS7 彻底卸载所有JDK/JRE + 重新安装JDK8(实操完整版,解决kafka/jps报错)
java·开发语言·kafka
一灰灰blog15 小时前
Spring AI中的多轮对话艺术:让大模型主动提问获取明确需求
数据库·人工智能·spring
Java水解16 小时前
【JAVA 进阶】Spring AOP核心原理:JDK与CGLib动态代理实战解析
后端·spring
暮色妖娆丶17 小时前
Spring 源码分析 BeanFactoryPostProcessor
spring boot·spring·源码
暮色妖娆丶19 小时前
SpringBoot 启动流程源码分析 ~ 它其实不复杂
spring boot·后端·spring