继续关于Kafka文档的阅读

This commit is contained in:
2023-03-02 16:21:35 +08:00
parent f7f3ce18ba
commit e608c50af1

View File

@@ -669,9 +669,33 @@ public ConcurrentMessageListenerContainer(ConsumerFactory<K, V> consumerFactory,
ConcurrentMessageListenerContainer还有一个concurrency属性例如`container.setConcurrency(3)`会创建3个`KafkaMessageListenerContainer`实例。 ConcurrentMessageListenerContainer还有一个concurrency属性例如`container.setConcurrency(3)`会创建3个`KafkaMessageListenerContainer`实例。
kafka会根据其组管理功能再消费者之间分配分区。 kafka会根据其组管理功能再消费者之间分配分区。
> **kafka分配策略** > **kafka分配策略**
> 当监听多个topic时默认的分区分配策略可能并不是想要的。例如有三个topic每个topic有5个分区那么将concurrency设置为15时只会看到5个活跃的consumer其余的10个consumer都会空闲。 > 当监听多个topic时默认的分区分配策略可能并不是想要的。例如有三个topic每个topic有5个分区那么将concurrency设置为15时只会看到5个活跃的consumer
> **RangeAssignor** > **RangeAssignor**
> 默认情况下kafka的分区分配策略是通过RangeAssignor来进行分配的其会将每个topic的分区在消费者group中所有消费者实例之间进行分配如果消费者实例数大于分区数则是会将消费者按字典顺序排序且分配分区给排序靠前的人。 > 默认情况下kafka的分区分配策略是通过RangeAssignor来进行分配的其会将每个topic的分区在消费者group中所有消费者实例之间进行分配如果消费者实例数大于分区数则是会将消费者按字典顺序排序且分配分区给排序靠前的人。
> 故而在RangeAssignor策略下只有字典排序靠前的消费者实例才能在每个topic中分配到一个分区前5个消费者每个实例3个分区后面的10个消费者完全空闲。 > 故而在RangeAssignor策略下只有字典排序靠前的消费者实例才能在每个topic中分配到一个分区前5个消费者每个实例3个分区后面的10个消费者完全空闲。
> **RoundRobinAssignor** > **RoundRobinAssignor**
> 相对于RangeAssignorRoundRobinAssingor则是会基于轮询在所有消费者之间均匀的分配所有的分区在上述情况下15个消费者实例每个都会分配到一个分区 > 相对于RangeAssignorRoundRobinAssingor则是会基于轮询在所有消费者之间均匀的分配所有的分区在上述情况下15个消费者实例每个都会分配到一个分区
>
> 想要改变`PartitionAssignor`可以再提供给DefaultKafkaConsumerFactory的参数中设置`ConsumerConfigs.PARTITION_ASSIGNMENT_STRATEGY_CONFIG`属性。
> 如果使用Spring Boot可以按如下方式来配置
> ```properties
> spring.kafka.consumer.properties.partition.assignment.strategy=
> org.apache.kafka.clients.consumer.RoundRobinAssignor
> ```
如果container属性通过`TopicPartitionOffset`配置,`ConcurrentMessageListenerContainer`将会把TopicPartitionOffset分发给所有其委托的KafkaMessageListenerContainer实例。
> 如果提供了六个TopicPartitionOffset实例并且concurrency被设置为3那么每个实例都会获取到2个分区。
> 如果5个TopicPartitionOffset实例被提供且concurrency被设置为2那么两个实例会获取到2个分区一个实例会获取到一个分区。
> 如果concurrency比TopicPartitionOffset的数量更大那么concurrency会向下进行调整让每个实例都获取一个分区。
**Committing Offsets**
如果消费者属性`enable.auto.commit`被设置为trueKafka会对offset进行自动提交。如果该选项被设置为falsecontainer支持一些`AckMode`设置。默认的`AckMode`值为`Batch``enable.auto.commit`被默认设置为false如果想要开启自动提交可以手动将该属性设置为true。
消费者的poll方法会返回一个或者多个ConsumerRecord。MessageListener对于每条record都会被调用。
根据`AckMode`的值container会执行如下操作
- RECORD当listener处理完record返回之后会提交Offset
- BATCH当poll方法返回的所有record都被处理之后提交Offset
- TIME当poll方法返回的所有record都被处理之后提交Offset或者自上次提交之后已经超过了ackTime也会提交Offset
- COUNT当poll方法返回的所有record都被处理之后提交Offset或者自从上次提交之后已经接收了超过ackCount条record也会被提交
- COUNT_TIME和TIME和COUNT类似但是只要TIME和COUNT任一满足也会提交Offset
- MANNUALmessage listener负责调用`Acknowledgment.acknowledge()`方法。除此之外和BATCH语义相同
- MANNUAL_IMMEDIATE当listener调用`Acknowledgment.acknowledge()`之后对Offset进行提交