注意:
当前的 Kafka 版本无法保证每个消息“只被保存一次”。现实中的很多应用程序在消息里加入唯一标识符,用于检测重复消息,消费者在读取消息时可以对它们进行清理。应用程序需要可以做到消息的“幂等”,也就是说,即使出现了重复消息,也不会对处理结果的正确性造成负面影响。
整合SpringBoot kafka,加入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
1. 新建或者更新主题
KafkaConfig.java
/**
* Description: kafka相关配置
*
* @author Xander
* datetime: 2021-01-08 17:40
*/
@Configuration
public class KafkaConfig {
/**
* 主题
*/
public static final String TOPIC_SPRING_KAFKA = "SpringKafka";
/**
* 新建或者更新Topic并设置分区数为3,分区副本数为1,
* 这里设置仅仅时测试使用,主题的分区数和每个分区的副本数,需要根据业务场景和硬件条件去考虑
* <p>
* 我们也可以不手动创建topic,因为kafka server.properties 配置文件中 auto.create.topics.enable 默认为 true,
* 表示如果主题不存在,则自动创建主题,
* 分区数量由kafka server.properties 配置文件中 num.partitions 指定,默认是 1
* 所以如果是自动创建主题,则默认的分区数为1,分区副本数为1
*
* @return
*/
@Bean
public NewTopic newOrUpdateTopic() {
// 通过TopicBuilder新建或者update Topic,
// 注意:主题的分区只能新增,不能减少分区
return TopicBuilder.name(TOPIC_SPRING_KAFKA).replicas(1).partitions(3).build();
}
}
我们也可以不手动创建主题,因为kafka server.properties 配置文件中 auto.create.topics.enable
默认为 true,表示如果主题不存在,则自动创建主题,分区数量由kafka server.properties 配置文件中 num.partitions
指定,默认是 1,所以如果这里不手动创建主题的话,kafka如果检查到主题不存在,会自动新建分区数和副本数都为1的主题。
注意: 如果主题已存在,NewTopic如果要update已存在的主题,分区数只能大于等于已有的分区数,不能减少分区。
2. SpringBoot kafka 配置
常用的生产者和消费者相关的配置都列出来,并表明了注释。
application.yml
spring:
kafka:
# kafka集群broker列表 host1:por1,host2:port2,host3:port3
bootstrap-servers: docker01:9092
########生产者配置########
producer:
# compression-type 消息的压缩算法
# 默认情况下是 none,消息发送时不会被压缩。 该参数可以设置为 none, gzip, snappy, lz4, zstd
compression-type: none
# acks 有多少个分区副本收到消息,生产者才会认为消息写入是成功的,只能选(0、1、all)
acks: all
# bufferMemory 生产者内存缓冲区的大小,下面是32MB
bufferMemory: 33554432
# retries 发生临时性的错误(比如分区找不到首领)重试次数,
# 默认情况下,生产者会在每次重试之间等待 100 ms,可以通过 retry.backoff.ms 参数来改变这个时间间隔
retries: 3
# key和value 的序列化器,这两个默认是 StringSerializer.class
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
# batch-size 批次大小,按照字节数计算
batch-size: 1024
properties:
# 自定义分区器
# partitioner:
# class: com.xander.kafka.partitioner.XdPartitioner
# request.timeout.ms 在发送数据时等待服务器返回响应的时间
request:
timeout:
ms: 1000
# 发送批次之前等待更多消息加入批次的时间
# linger.ms为0,表示生产者每条消息都直接提交给kafka,不等待批次,这时候batch-size其实就没用了
linger:
ms: 100
# retry.backoff.ms 每次重试之间的时间间隔,默认是100ms,这里配置50ms
retry:
backoff:
ms: 50
# max.in.flight.requests.per.connection 在收到服务器响应之前可以发送多少个消息,如果不需要保证消息顺序性的场景,建议不用配置该属性
# 把它设为 1 可以保证消息在同一个生产者的某一个分区上,是按照发送的顺序写入服务器的,即使发生了重试。但是会降低Kafka的吞吐量
max:
in:
flight:
requests:
per:
connection: 1
#