一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
前言
为了让消息能按照我们预期的方式进行消费,首先我们要了解Kafka 的消费模型,熟知 Kafka 的基本概念,关于这些,我在「Kafka 系列」- Kafka 入门 一文中有详细的介绍。
当我们掌握基础知识以后,就可以对程序发送到 Kafka 的逻辑进行控制,比如:
- 是否对有序性的要求高,来决定是否只发往一个 Partition?
- 发送失败怎么办,是否重试,重试多少次,每次的间隔是多少,还是用其他逻辑来处理失败的消息?
- 同步发送还是异步发送?
- ……
如下图,要想知道有多少个参数可以配置的话,可以搜索 KafkaProperties 这个类,里面有一个内部类 Producer,这个内部类的成员,就是我们可以配置的参数。
在这里,我们挑选几个重要的、常见的参数详解。
spring.kafka.producer.acks
由于 Kafka 的多副本机制(Replica ),我们平时只和 Leader 打交道,发送消息和接收消息都在 Leader 中,随后小弟们会自动的从 Leader 中拉取消息进行同步。
这个参数的配置,是生产者要求 Leader 在响应完成请求之前收到的确认数,每个小弟从 Leader 同步了这条消息,都会收到一个确认消息,确认数达到我们配置的值,Leader 就会返回收到这条消息的响应。
acks 是生产者客户端中一个非常重要的参数,它涉及消息的可靠性和吞吐量之间的权衡,该参数可以有三个值:
-
acks = all,意味着 Leader 将等待完整的同步副本集以确认记录,这保证了只要至少一个同步副本服务器仍然存活,记录就不会丢失,这是最强有力的保证,这相当于 acks = -1 的设置。
-
acks = 1,意味着leader会将记录写入其本地日志,但无需等待所有副本服务器的完全确认即可做出回应,在这种情况下,如果leader在确认记录后立即失败,但在将数据复制到所有的副本服务器之前,则记录将会丢失。
-
acks = 0,如果设置为零,则生产者将不会等待来自服务器的任何确认,该记录将立即添加到套接字缓冲区并视为已发送;在这种情况下,无法保证服务器已收到记录,并且重试机制将不会生效(因为客户端不会收到任何异常),为每条记录返回的偏移量始终设置为 -1。
配置示例:
spring.kafka.producer.acks = all
spring.kafka.producer.retries
该参数用来配置生产者重试的次数
当生产者遇到如网络抖动、Leader 副本选举等情况的时候,可能会出现发送失败的情况,但这种异常往往是可以自行恢复的 当重试次数配置大于0时,生产者会自己尝试重新发送,而不是一味地将异常抛给生产者的应用程序。如果重试达到设定的次数,那么生产者就会放弃重试并返回异常。
不过并不是所有的异常都是可以通过重试来解决的,比如消息太大,超过max.request.size参数配置的值时,这种方式就不可行了。
该参数直接配置为大于 0 的数字,但也要合理配置。
示例:
spring.kafka.producer.retries = 1
需要注意的是,如果使用了异步发送的方法,并且配置了较长的重试间隔时间,有可能出现消息顺序性不一致的问题,对于顺序性要求高的程序需要注意
spring.kafka.producer.properties.retry.backoff.ms
该参数用于配置重试机制的间隔时间,常与参数 spring.kafka.producer.retries 配合使用,默认值为 100。
示例:
spring.kafka.producer.properties.retry.backoff.ms = 100
spring.kafka.producer.batch-size
每当多个记录被发送到同一分区时,生产者尝试将记录一起批量处理为更少的请求;这有助于提升客户端和服务端之间的性能,此配置控制默认批量大小(以字节为单位),默认值为16384
示例:
spring.kafka.producer.batch-size=16384
指定消息的序列化方式
我们可以为 key 和 value 指定序列化方式,这涉及到两个配置:
spring.kafka.producer.key-serializerspring.kafka.producer.value-serializer
如果你是在不知道要配置什么值,可以先查看接口 org.apache.kafka.common.serialization.Serializer ,通过查看实现类的方式,就可以得到一堆实现类
示例:
spring.kafka.producer.key-serializer = org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
最后
对于一般的消息队列来说,掌握这几个生产参数的配置已经足够使用了,当然了,我们也不需要将它背下来,做一个了解,在需要的时候能想出来有这么一个东西存在,可以配置;抑或是遇到问题后,我们知道能通过某个配置项来解决问题即可