Springboot整合kafka(MQ)

概念

  • 一个topic主题下面有多个分区(比如partition1、partition2、partition3),每个分区有多个副本;从所有的副本中选取一个作为Leader,其他作为Follower,Leader副本 负责消息的接收和消息的消费,Follower只负责数据的同步;当Leader分区故障后,从Follower中选取一个作为新的Leader

  • 一个分区partition只能被消费者组中的一个消费者实例消费,当topic中分区数量发生变化 或者 消费者组中的消费者发生变化 会触发rebalance,重新分配分区partition和消费者实例 之间的关系

  • 生产者发送的消息只在一个partition分区内有序,如果topic下面有多个分区,那所有消息整体是无序的

  • 一个topic可以有多个消费者组,kafka会记录每个"消费者组" 消费到 "哪个分区的哪个偏移量offset"了

下载

  • 下载地址:kafka.apache.org/community/d...

  • 在/root/kafka/kafka_2.12-3.6.2目录下创建文件夹mq_logs,并在mq_logs文件夹下分别创建文件夹kafka_data_logs和zookeeper_data分别保存kafka的日志数据和zookeeper的数据

  • 在mq_logs目录下创建kafka_console.out和zookeeper_console.out保存启动程序时的日志输出

  • 进入config目录修改zookeeper.properties,将dataDir改为:dataDir=/root/kafka/kafka_2.12-3.6.2/mq_logs/zookeeper_data

  • 进入config目录修改server.properties

    • 将log.dir改为log.dirs=/root/kafka/kafka_2.12-3.6.2/mq_logs/kafka_data_logs

    • 添加配置:listeners=PLAINTEXT://0.0.0.0:9092和 advertised.listeners=PLAINTEXT://localhost:9092

启动

  • 先启动zookeeper:nohup bin/zookeeper-server-start.sh config/zookeeper.properties > /root/kafka/kafka_2.12-3.6.2/mq_logs/zookeeper_console.out 2>&1 &

  • 再启动kafka:nohup bin/kafka-server-start.sh config/server.properties > /root/kafka/kafka_2.12-3.6.2/mq_logs/kafka_console.out 2>&1 &

命令

  • 创建主题:./kafka-topics.sh --create --topic 主题名称 --bootstrap-server localhost:9092

  • 查看所有主题:./kafka-topics.sh --list --bootstrap-server localhost:9092

  • 查看某个主题:./kafka-topics.sh --describe --topic 主题名称 --bootstrap-server localhost:9092

  • 删除某个主题:./kafka-topics.sh --delete --topic 主题名称 --bootstrap-server localhost:9092

  • 查看某个组的消费情况:./kafka-consumer-groups.sh --describe --group 消费者组名称 --bootstrap-server localhost:9092

  • 查看某个组下面的消费者:./kafka-consumer-groups.sh --describe --group 消费组名称 --bootstrap-server localhost:9092 --members

springboot整合kafka

  • 引入依赖

    java 复制代码
    <dependency>
        <groupId>org.springframework.kafka</groupId>
        <artifactId>spring-kafka</artifactId>
    </dependency>
  • 引入配置

    properties 复制代码
    spring.kafka.bootstrap-servers=115.190.156.159:9092
    spring.kafka.producer.retries=3
    spring.kafka.producer.batch-size=1000
    spring.kafka.producer.buffer-memory=33554432
    
    spring.kafka.consumer.group-id=crm-microservice-newperformance
    spring.kafka.consumer.enable-auto-commit=false
    spring.kafka.consumer.auto-offset-reset=earliest
    spring.kafka.consumer.max-poll-records=200
    spring.kafka.listener.ack-mode=MANUAL_IMMEDIATE
  • 配置类:如果程序异常,spring默认将这条消息重复处理9次;这里配置的是同一消息 多次消费失败 的处理策略,即转发到另一个死信topic中;注意,这里是springboot2.7及以上版本的配置方式,和2.7以下版本配置方法不同

    java 复制代码
    @Component
    public class KafkaConfig {
        @Bean
        public CommonErrorHandler errorHandler(KafkaTemplate<Object, Object> template) {
            // 1. 定义死信恢复器,当重试耗尽后,将消息转发到 "原Topic.DLT"
            DeadLetterPublishingRecoverer recover = new DeadLetterPublishingRecoverer(template);
            
            // 2. 定义错误处理器
            DefaultErrorHandler errorHandler = new DefaultErrorHandler(recover, new FixedBackOff(1000L, 3));
    
            return errorHandler;
        }
    }
  • 生产者

    java 复制代码
    @CrossOrigin
    @RestController
    @RequestMapping("/kafka")
    public class KafkaController {
        @Autowired
        private KafkaTemplate<String, String> kafkaTemplate;
    
        @RequestMapping("/send")
        public String send() throws InterruptedException, ExecutionException {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("userid", 1001);
            map.put("name", "ccb"+ UUID.randomUUID());
    
            ListenableFuture<SendResult<String, String>> result = kafkaTemplate.send("test_ccb", JSONObject.toJSONString(map));
            System.out.println("发送结果:"+result.get());
            return "ok";
        }
    }
  • 消费者

    java 复制代码
    public class KafkaConsumer {
    
        // 这里的concurrency=5代表会创建5个消费者实例
        @KafkaListener(topics = {"test_ccb"},concurrency = "5")
        public void consumer(ConsumerRecord<?, ?> consumerRecord, Acknowledgment ack) {
            System.out.println("收到消息:" + consumerRecord);
            ack.acknowledge();
        }
    }

Spring-Kafka原理

  • spring-kafka的自动配置类中,通过KafkaListenerAnnotationBeanPostProcessor 扫描每个Bean对象是否带有@KafkaListener注解,如果有则提取注解上的topics、groupId、concurrency等信息封装成一个Endpoint对象,根据Endpoint指定的容器工厂containerFactory创建容器,在容器内运行KafkaConsumer
  • 容器工厂是ConcurrentKafkaListenerContainerFactory,它生产容器KafkaMessageListenerContainer,在容器内运行KafkaConsumer,如果concurrency设置为3,将创建3个容器,也就是会有3个消费者实例
  • 如果程序处理过程中出现了错误,会调用配置好的 CommonErrorHandler进行处理,默认会重试9次,如果还是失败,则提交该偏移量避免阻塞后续消息
  • gemini3剖析过程:gemini.google.com/share/4de80...

相关文章

相关推荐
ZhengEnCi3 小时前
模型训练完整流程:从数据准备到模型上线的 10 个关键步骤(全文可跑)
后端·算法
王中阳Go3 小时前
后端转 Agent 岗面试怎么答:8 个高频问题与应答口径
人工智能·后端·python·大语言模型
程序猿DD3 小时前
OctaFuse Gateway 2.18.0:MCP 接入支持 OAuth,供应商粘性绑定可视化管理
后端
ZhengEnCi5 小时前
Agent 规则管理:让 Memory 做索引、让 Skill 存规则——上下文上限实测与分工方案
后端
nice_lcj5205 小时前
深入理解 Java 反射:从 Class 对象到方法调用(含性能实测 + 迷你 IOC 实战 + 面试考点)
java·开发语言·后端·面试
骑着蜗牛撵大象3276 小时前
2026 后端 AI 工程化:Spring AI 管调用、MCP 管工具、Agent 内嵌管自治
java·人工智能·后端·spring·ai·可观测性·mcp
摸爬滚打的小李6 小时前
Spring XML + WAR + Tomcat 项目启动
后端
IT_陈寒7 小时前
SpringBoot自动配置的坑,这次终于爬出来了
前端·人工智能·后端
RainbowFish7 小时前
# RAG 与智能体记忆:从原理到工程实践 > 一篇给学习者的总结。
后端
苏三说技术8 小时前
为什么越来越多人用Arthas 4 ?
后端