我正在设置ConcurrentMessageListenerContainer
<bean class="org.springframework.kafka.listener.ConcurrentMessageListenerContainer" id="messageListenerContainer">
<constructor-arg index="0" ref="consumerFactory"/>
<constructor-arg index="1" ref="containerProperties"/>
<property name="concurrency" value="2"/>
</bean>
ConsumerFactory使用此配置:
<util:map id="consumerConfig" map-class="java.util.HashMap">
<entry key="#{T(org.apache.kafka.clients.consumer.ConsumerConfig).BOOTSTRAP_SERVERS_CONFIG}"
value="${rp.kafka.bootstrap.servers}"/>
<entry key="#{T(org.apache.kafka.clients.consumer.ConsumerConfig).KEY_DESERIALIZER_CLASS_CONFIG}"
value="org.apache.kafka.common.serialization.StringDeserializer"/>
<entry key="#{T(org.apache.kafka.clients.consumer.ConsumerConfig).VALUE_DESERIALIZER_CLASS_CONFIG}"
value="org.springframework.kafka.support.serializer.JsonDeserializer"/>
<entry key="#{T(org.springframework.kafka.support.serializer.JsonDeserializer).TRUSTED_PACKAGES}"
value="*"/>
<entry key="#{T(org.apache.kafka.clients.consumer.ConsumerConfig).PARTITION_ASSIGNMENT_STRATEGY_CONFIG}"
value="org.apache.kafka.clients.consumer.RoundRobinAssignor"/>
<entry key="#{T(org.apache.kafka.clients.consumer.ConsumerConfig).ENABLE_AUTO_COMMIT_CONFIG}"
value="false"/>
</util:map>
和ContainerProperty是
<bean class="org.springframework.kafka.listener.ContainerProperties" id="containerProperties">
<constructor-arg>
<list>
<value>sendSMS</value>
</list>
</constructor-arg>
<property name="groupId" value="main"/>
<property name="messageListener" ref="messageListener"/>
<property name="ackMode" value="RECORD"/>
</bean>
我的主题“ sendSMS”在3节点群集上有5个分区,表示因子为3,因此我希望由并发创建的每个KafkaMessageListenerContainer(在这种情况下共2个)将占用一部分分区。但是,在启动应用程序后,我在调试器窗口中看到每个侦听器都在处理所有5个侦听器!隔断 https://gyazo.com/183626ff60061b471858f8cc52573353 和来自第4个分区的消息(在该消息中,我有一个挂起处理的消息,并且在重启后未提交,但与该问题无关),在相同偏移量上的第4个分区在具有不同使用者的不同线程中传递了2次!为什么会这样呢?是错误还是预期的行为?
答案 0 :(得分:0)
您没有显示足够的信息。并发容器聚合子KafkaListenerContainer
的分配分区(每个并发分配一个)。
@Override
public Collection<TopicPartition> getAssignedPartitions() {
return this.containers.stream()
.map(KafkaMessageListenerContainer::getAssignedPartitions)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
您需要显示重新交付的日志;打开调试日志记录以获取更多信息。