繁体   English   中英

在同一个 Kafka 主题中监听多种类型的对象

[英]Listen to multiple type of objects in the same Kafka topic

我有一个用例,我将在同一主题中接收两种 object。 我面临的问题是所有的对象都去同一个听众。 未使用第二个侦听器。

我的听众类似于下面

@EnableKafka
@Service
public class consumerService {

  @KafkaListener(topic = "t", groupId = "g" containerFactory = "fooContainerFactory")
  public void consume1(Foo foo) {
     logger.info("I got : " + foo);
  }

  @KafkaListener(topic = "t", groupId = "g" containerFactory = "barContainerFactory")
  public void consume2(Bar bar) {
     logger.info("I got : " + bar);
  }

}

Foo 的容器工厂在下面,我有一个类似的 Bar。

@Configuration
public class MyConsumerConfig {


  @Value(value = "${kafka.bootstrapAddress}")
  private String bootstrapAddress;

  @Value(value = "${group.id}")
  private String groupId;

  public Map<String, Object> clickConsumerFactory() {
    /** Set the consumer properties here */
    Map<String, Object> props = new HashMap<>();
    props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
    props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
    props.put(JsonDeserializer.TRUSTED_PACKAGES, "*");
    return props;
  }

  @Bean
  public ConcurrentKafkaListenerContainerFactory<String, Foo> clickKafkaListenerContainerFactory() {
    /** Listener factory for the class 'Foo' */
    ConcurrentKafkaListenerContainerFactory<String, Foo> factory
            = new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConsumerFactory(new DefaultKafkaConsumerFactory<>(clickConsumerFactory()));
    factory.setMessageConverter(new StringJsonMessageConverter());
    factory.setErrorHandler(((exception, data) -> LOGGER.info("There was an error " + exception)));
    return factory;
  }
}

我尝试使用 KafkaHandler,但我不知道如何指定单个容器工厂(对于 Foo:FooContainerFactory,对于 Bar:BarContainerFactory)我被困了几个小时。 有人能告诉我我应该改变什么吗?

我可能会离开这里。 因为我不确定@KafkaListener 是如何工作的。 但是,在我的脑海中,有可能只有一个分区并且第一个 kakfaListener 被分配给它。 因此,任何新的侦听器(类似于 kafka 消费者)都不会被分配任何分区,因为开始时只有 1 个分区。 因此,新的侦听器将闲置等待分配某个分区,以便他们可以开始读取数据。

您可以通过禁用第一个 KafkaListener 然后运行您的应用程序来验证这一点。 第二个听众会自动加入。

或者,如果您的主题已经有多个分区,则可能由于消息的键而发生这种情况,因为键可用于将数据发送到一个分区。 并且您的第一个侦听器被分配给该分区。

你不能那样做。 如果同一个主题同时包含 Foo 和 Bar 对象; 框架无法过滤掉不匹配的记录。

而且,正如在其他评论中所说的那样,答案,因为它们都在同一个组中,所以他们每个人都会得到一个记录子集。

最简单的解决方案是使用两个不同的主题。

如果这不可能,您必须使用带有@KafkaHandler方法的 class 级别的侦听器,但是您需要在反序列化器中进行转换,而不是框架从方法参数中找出类型。

有关显示如何执行此操作的示例的链接,请参阅此答案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM