Java 春季卡夫卡-试图了解事物在幕后是如何运作的

Java 春季卡夫卡-试图了解事物在幕后是如何运作的,java,spring,spring-kafka,Java,Spring,Spring Kafka,考虑以下代码- @Bean public ConsumerFactory<String, String> consumerFactory() { Map<String, Object> props = new HashMap<>(); props.put( ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress); props.put( C

考虑以下代码-

@Bean
public ConsumerFactory<String, String> consumerFactory() {
    Map<String, Object> props = new HashMap<>();
    props.put(
      ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, 
      bootstrapAddress);
    props.put(
      ConsumerConfig.GROUP_ID_CONFIG, 
      groupId);
    props.put(
      ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, 
      StringDeserializer.class);
    props.put(
      ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, 
      StringDeserializer.class);
    return new DefaultKafkaConsumerFactory<>(props);
}

@Bean
public ConcurrentKafkaListenerContainerFactory<String, String> 
  kafkaListenerContainerFactory() {

    ConcurrentKafkaListenerContainerFactory<String, String> factory
      = new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConsumerFactory(consumerFactory());
    return factory;
}

当我没有设置concurrency属性时,Spring会创建1个使用者实例,1个kafka侦听器容器,属于使用者工厂中指定的组吗

如果我将并发性更改为3,spring是否会创建3个使用者实例,从而在配置使用者工厂和3个侦听器容器时指定的同一使用者组中有3个使用者

另外,根据并发性,假设我们现在只听一个主题,我们将有3个方法用@kafkalistener注释,如果未指定分区,则所有3个方法都会听不同的分区(由kafka以循环方式提供)


我是Kafka新手,希望澄清我的理解。

当我不设置concurrency属性时,Spring是否会创建一个消费者实例,一个Kafka侦听器容器,属于消费者工厂中指定的组

您将有一个使用者从该主题的所有分区获取事件

如果我将并发性更改为3,spring是否会创建3个使用者实例,从而在配置使用者工厂和3个侦听器容器时指定的同一使用者组中有3个使用者

您将有3个使用者实例,如果您在该主题中至少有3个分区,那么每个实例都将从其中一个分区获取事件。使用者将事件传递到该KafkaListener实例

你可以说得更具体一些

另外,根据并发性,假设我们现在只听一个主题,我们将有3个方法用@kafkalistener注释,如果未指定分区,则所有3个方法都会听不同的分区(由kafka以循环方式提供)

这是没有道理的。首先,《卡夫卡列传》是对《春天卡夫卡》的高级抽象,卡夫卡根本不会循环(从消费者的角度看,它与制作人不同),如果你有3个消费者(同一消费者群体+听同一主题),主题中有3个分区,Kafka将重新平衡并将一个分区分配给一个使用者,每个使用者将仅从Kafka分配的分区获取事件。Spring Kafka在每个使用者中接收事件后,将在KafkaListener实例中传递事件


当我没有设置concurrency属性时,Spring会创建1个使用者实例,1个kafka侦听器容器,属于使用者工厂中指定的组吗

您将有一个使用者从该主题的所有分区获取事件

如果我将并发性更改为3,spring是否会创建3个使用者实例,从而在配置使用者工厂和3个侦听器容器时指定的同一使用者组中有3个使用者

您将有3个使用者实例,如果您在该主题中至少有3个分区,那么每个实例都将从其中一个分区获取事件。使用者将事件传递到该KafkaListener实例

你可以说得更具体一些

另外,根据并发性,假设我们现在只听一个主题,我们将有3个方法用@kafkalistener注释,如果未指定分区,则所有3个方法都会听不同的分区(由kafka以循环方式提供)

这是没有道理的。首先,《卡夫卡列传》是对《春天卡夫卡》的高级抽象,卡夫卡根本不会循环(从消费者的角度看,它与制作人不同),如果你有3个消费者(同一消费者群体+听同一主题),主题中有3个分区,Kafka将重新平衡并将一个分区分配给一个使用者,每个使用者将仅从Kafka分配的分区获取事件。Spring Kafka在每个使用者中接收事件后,将在KafkaListener实例中传递事件


你觉得这篇文章怎么样,丹尼?我的理解是基于此。而且,我的最后一个问题没有被恰当地提出?但这就是我想说的,并发性3所以3个使用者实例,每个使用者实例从一个主题的3个分区之一获取消息,并将消息提供给侦听器容器(每个使用者实例都有一个)这将为总共3个方法中的每一个方法提供@kafkaListener注释。如果您有3个
@kafkaListener
,则每个方法都将从配置的主题中分配分区。如果他们有相同的主题和不同的
group.id
,他们将获得每条消息的副本。如果它们具有相同的
group.id
,并且正在使用组管理,则Kafka将跨实例分发主题/分区。如果每个主题只有一个分区,则不能保证每个主题都有一个分区;最有可能的情况是,一个实例将从每个主题中获得单个分区,而另外两个实例将处于空闲状态。最后一个问题,组id是在kafka服务器上注册的,还是仅在用户端有意义?如果我在两台不同的机器上部署了两个应用程序。在每个应用程序中,我都有一个侦听器,并且消费者工厂配置了相同的组id,两台独立机器上的两个侦听器是否成为同一消费者组的一部分?这是正确的。这就是ApacheKafka中
消费者组
功能的标准用途。具有相同组的所有使用者都在代理上注册,并且当只有一个使用者可以访问每个分区时,它们被视为一个成员。请阅读更多卡夫卡文档,你如何评价这篇文章,丹尼?我的理解是基于此。而且,我的最后一个问题没有被恰当地提出?但这就是我想说的,并发3所以3个使用者实例,每个实例从一个主题的3个分区中的一个获取消息,并将消息提供给侦听器容器(每个使用者实例都有一个),侦听器容器将为每个方法提供消息
@KafkaListener(topics = "topicName")
public void listen(String message) {
    System.out.println("Received Message: " + message);
@KafkaListener(
  topicPartitions = @TopicPartition(topic = "topicName",
  partitionOffsets = {
    @PartitionOffset(partition = "0", initialOffset = "0"), 
    @PartitionOffset(partition = "3", initialOffset = "0")
}))
public void listenToParition(
  @Payload String message, 
  @Header(KafkaHeaders.RECEIVED_PARTITION_ID) int partition) {
      System.out.println(
        "Received Messasge: " + message"
        + "from partition: " + partition);
}