kafka 初识

文章摘要:本文从作者接触MQ技术的经历谈起,对比了ActiveMQ、RocketMQ和Kafka的异同,重点介绍了Spring Kafka的基础入门配置。文章详细讲解了Maven依赖配置、Spring自动装配数据、KafkaTemplate使用、@MessageListener注解以及自定义Container的实现方法,为Java开发者提供了实用的Spring Kafka配置指南。

闲谈

还记得多年前实现的时候第一次接触的MQ 类型是ActiveMQ,在那个时候的应用场景完成能够支撑得住。

后来换了一家公司,全部标配 Rocketmq,RocketMQ 经过多年阿里内部的实践已经是一款非常优秀的MQ产品了。

Rocketmq和kafka很多概念非常的相似,之前一直没有在产品中使用过kafka,最近接手两个产品都使用了Kafka,了解一下相关的原理。

为什么说Kafka和Rocketmq 很多概念是类似的?

Kafka中,1个Partition只能被1个消费线程消费。

Rocketmq中1个队列只能被一个消费者线程消费。

如果消费线程大于分区(队列)数,则多余的消费线程将空闲;如果消费线程小于分区(队列)数,则有部分消费线程将消费多个分区(队列)的数据;

如果消费线程等于分区(队列)数,则刚刚好一个消费线程对应一个分区,这也是最理想的情况.

恰好看到生产环境Kafka的分区数Only 配置了3个分区,消费者组2个线程,一共部署了十台实例,其实很多集群都是无用的。

基于对Rocketmq 的理解 ,其实针对 Kafka的理解就非常容易。 Kafka初识之架构之美 写得非常不错。

spring kafka 基础入门

配置maven 依赖

仔细阅读官方文档 spring-kafka 2.9.13

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

配置spring 自动装配的数据

propertis 复制代码
###########【Kafka集群】###########
spring.kafka.bootstrap-servers=
  
###########【初始化消费者配置】###########
# 默认的消费组ID
#spring.kafka.consumer.properties.group.id=longConnConsumerGroup
# 是否自动提交offset
spring.kafka.consumer.enable-auto-commit=false
  
spring.kafka.listener.ack-mode=manual_immediate
# 提交offset延时(接收到消息后多久提交offset)
#spring.kafka.consumer.auto.commit.interval.ms=1000
# 当kafka中没有初始offset或offset超出范围时将自动重置offset
# earliest:重置为分区中最小的offset;
# latest:重置为分区中最新的offset(消费分区中新产生的数据);
# none:只要有一个分区不存在已提交的offset,就抛出异常;
spring.kafka.consumer.auto-offset-reset=latest
# 消费会话超时时间(超过这个时间consumer没有发送心跳,就会触发rebalance操作)
spring.kafka.consumer.properties.session.timeout.ms=240000
# 消费请求超时时间
spring.kafka.consumer.properties.request.timeout.ms=240000
spring.kafka.consumer.properties.max.poll.interval.ms=240000
spring.kafka.consumer.properties.heartbeat.interval.ms=80000
# Kafka提供的序列化和反序列化类
spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
# 消费端监听的topic不存在时,项目启动会报错(关掉)
spring.kafka.listener.missing-topics-fatal=false
# 设置批量消费
spring.kafka.listener.type=batch
#并发数
spring.kafka.listener.concurrency=2
# 批量消费每次最多消费多少条消息
spring.kafka.consumer.max-poll-records=3
spring.kafka.consumer.client-id=
  
###########【初始化生产者配置】###########
## 重试次数
spring.kafka.producer.retries=2
## 应答级别:多少个分区副本备份完成时向生产者发送ack确认(可选0、1、all/-1)
#acks = 0 如果设置为零,则生产者将不会等待来自服务器的任何确认,该记录将立即添加到套接字缓冲区并视为已发送。在这种情况下,无法保证服务器已收到记录,并且重试配置将不会生效(因为客户端通常不会知道任何故障),为每条记录返回的偏移量始终设置为-1。
#acks = 1 这意味着leader会将记录写入其本地日志,但无需等待所有副本服务器的完全确认即可做出回应,在这种情况下,如果leader在确认记录后立即失败,但在将数据复制到所有的副本服务器之前,则记录将会丢失。
#acks = all 这意味着leader将等待完整的同步副本集以确认记录,这保证了只要至少一个同步副本服务器仍然存活,记录就不会丢失,这是最强有力的保证,这相当于acks = -1的设置。
spring.kafka.producer.acks=-1
## 批量大小
#spring.kafka.producer.batch-size=16384
## 提交延时
#spring.kafka.producer.properties.linger.ms=0
## 当生产端积累的消息达到batch-size或接收到消息linger.ms后,生产者就会将消息提交给kafka
## linger.ms为0表示每接收到一条消息就提交给kafka,这时候batch-size其实就没用了
#?
## 生产端缓冲区大小
#spring.kafka.producer.buffer-memory = 33554432
## Kafka提供的序列化和反序列化类
#spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
#spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
## 自定义分区器
## spring.kafka.producer.properties.partitioner.class=com.felix.kafka.producer.CustomizePartitioner
#开启生产幂等
spring.kafka.producer.properties.enable.idempotence=true
spring.kafka.producer.client-id=

kafka-template

java 复制代码
 kafkaTemplate.send(new ProducerRecord<>(topic, message));

@MessageListener

concurrency 消费者数量和分区密切相关避免浪费

java 复制代码
@KafkaListener(clientIdPrefix = ""
            , topics = ""
            , concurrency = ""
            , groupId = "TEST_GROUP")
public void listen(List<ConsumerRecord> consumerRecords, Acknowledgment acknowledgment) {
  
    for (ConsumerRecord consumerRecord : consumerRecords) {
  
    }
    //消息确认
    acknowledgment.acknowledge();
}

广播消费...

java 复制代码
@KafkaListener(clientIdPrefix = ""
            , topics = ""
            , concurrency = ""
            , groupId = "#{T(java.util.UUID).randomUUID().toString()}")
public void listen(List<ConsumerRecord> consumerRecords, Acknowledgment acknowledgment) {
  
    for (ConsumerRecord consumerRecord : consumerRecords) {
  
    }
    //消息确认
    acknowledgment.acknowledge();
}

需要自定义 Container ?

Dynamically Creating Containers

比如下面这个配置消费者需要广播消费... 其实默认情况下spring 提供了默认的,不需配置全局统一就行了,广播消费这个直接可以在@KafkaListener处理。

java 复制代码
@Configuration
public class KafkaProducerConfig {
    private final ConsumerFactory consumerFactory;
    private final KafkaProperties kafkaProperties;
  
    @Bean("containerFactory")
    public ConcurrentKafkaListenerContainerFactory<String, String> containerFactory() {
        ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory();
        factory.setConsumerFactory(consumerFactory);
        //手动确认
        factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
        //批量消费
        factory.setBatchListener(true);
        factory.setConcurrency(kafkaProperties.getListener().getConcurrency());
        factory.getContainerProperties().setGroupId(getGroupId());
        return factory;
    }
  
    private String getGroupId() {
        String groupId;
        String inetAddress = HostNameUtil.getInetAddress();
        if (inetAddress == null) {
            groupId = UUID.randomUUID().toString().replace("-", "");
        } else {
            groupId = inetAddress.replace(".", "");
        }
        return groupId;
    }
}
  

参考资料

相关推荐
Shan12051 小时前
分布式锁的优势与互斥性
分布式
段一凡-华北理工大学1 小时前
工业领域的Hadoop架构学习~系列文章18:制造业Hadoop应用实践 - 从数据到智能的完整闭环
大数据·人工智能·hadoop·分布式·学习·架构·高炉炼铁
暗夜猎手-大魔王1 小时前
转载--Hermes Agent 企业级分布式部署方案
分布式
heimeiyingwang2 小时前
【架构实战】日志体系设计:从ELK到可观测性的演进
分布式·缓存·架构
可乐ea2 小时前
【知识获取与分享社区项目 | 项目日记第 24 天】终章总结:从认证、发布、计数、Feed、搜索到 RAG:完整复盘一个知识社区后端系统
java·spring boot·redis·mysql·elasticsearch·ai·kafka
Jabes.yang2 小时前
Java面试实录:AIGC场景下的Stream、微服务、Redis、Kafka与安全实战
java·spring boot·redis·微服务·面试·kafka·aigc
段一凡-华北理工大学2 小时前
工业领域的Hadoop架构学习~系列文章17:Hadoop性能调优- 调度集群每一分性能
大数据·人工智能·hadoop·分布式·学习·架构·高炉炼铁
我是一颗柠檬3 小时前
【Java项目技术亮点】Kafka异步写+写聚合:吞吐量提升10倍的消息队列优化秘籍
java·分布式·kafka·linq
闪电悠米3 小时前
黑马点评-秒杀优化-03_blocking_queue_async_order
数据库·分布式·oracle·junit·wpf·lua