概念
-
一个topic主题下面有多个分区(比如partition1、partition2、partition3),每个分区有多个副本;从所有的副本中选取一个作为Leader,其他作为Follower,Leader副本 负责消息的接收和消息的消费,Follower只负责数据的同步;当Leader分区故障后,从Follower中选取一个作为新的Leader
-
一个分区partition只能被消费者组中的一个消费者实例消费,当topic中分区数量发生变化 或者 消费者组中的消费者发生变化 会触发rebalance,重新分配分区partition和消费者实例 之间的关系
-
生产者发送的消息只在一个partition分区内有序,如果topic下面有多个分区,那所有消息整体是无序的
-
一个topic可以有多个消费者组,kafka会记录每个"消费者组" 消费到 "哪个分区的哪个偏移量offset"了

下载
-
在
/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> -
引入配置
propertiesspring.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"; } } -
消费者
javapublic 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...