简体   繁体   English

默认的 kafkaListenerContainerFactory 是如何工作的

[英]How does default kafkaListenerContainerFactory work

I have a kafka consumer java application.我有一个卡夫卡消费者 java 应用程序。 I am reading two separate kafka topics from that application.我正在从该应用程序中阅读两个单独的 kafka 主题。

For topic 1, there is a KafkaListenerContainerFactory with name kafkaListenerContainerFactory, below is the code snippet.对于主题 1,有一个名为 kafkaListenerContainerFactory 的 KafkaListenerContainerFactory,下面是代码片段。 The message is in avro format.消息采用 avro 格式。 Pojo1 is the pojo class built using avro schema. Pojo1 是使用 avro 模式构建的 pojo class。

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

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

    return factory;
}

For consuming message from topic1, we have below method为了消费来自 topic1 的消息,我们有以下方法

@kafkaListener (topics="topic1") public boolean readTopic1(ConsumerRecord<String,Pojo1> record){ // logic }

Now this application is reading messages form topic2 too which is also having avro messages and Pojo2 is the pojo class built using the respective avro schema.现在这个应用程序也在读取来自 topic2 的消息,它也有 avro 消息,Pojo2 是使用相应的 avro 模式构建的 pojo class。

To read from topic2, we have below method要从 topic2 中读取,我们有以下方法

@kafkaListener (topics="topic2") public boolean readTopic2(ConsumerRecord<String,Pojo2> record){ // logic }

Now I am not getting how consuming messages from topic2 is working as expected.现在我没有得到来自 topic2 的消费消息是如何按预期工作的。

kafkaListenerContainerFactory was configured with Pojo1 so how does messages are being read from topic2 for Pojo2. kafkaListenerContainerFactory 配置了 Pojo1,所以如何从 Pojo2 的 topic2 读取消息。 As far as I know kafka creates default container factory only if there is a missing bean with name "kafkaListenerContainerFactory", but in my application we already have built one kafkaListenerContainerFactory for topic1.据我所知,kafka 仅在缺少名为“kafkaListenerContainerFactory”的 bean 时才会创建默认容器工厂,但在我的应用程序中,我们已经为 topic1 构建了一个 kafkaListenerContainerFactory。

According there should be another KafkaListenerContainerFactory created for Pojo2 and should be given the reference when using @kafkaListener (topics="topic2", containerFactory="factoryForTopic2")根据应该有另一个为 Pojo2 创建的 KafkaListenerContainerFactory 并且应该在使用@kafkaListener (topics="topic2", containerFactory="factoryForTopic2")时给出参考

Can someone help me understand how KafkaListenerContainerFactory is working for different topics with different message schema's.有人可以帮助我了解 KafkaListenerContainerFactory 如何为具有不同消息模式的不同主题工作。

It's called type erasure;这称为类型擦除; the generic types are only applicable at compile time.泛型类型仅在编译时适用。 At runtime, as long as your deserializer creates the correct type it will work.在运行时,只要您的反序列化器创建正确的类型,它就可以工作。

It's probably cleaner to use ConcurrentKafkaListenerContainerFactory<String, Object> to avoid any confusion;使用ConcurrentKafkaListenerContainerFactory<String, Object>可能更干净,以避免任何混淆; especially when using an avro or json deserializer that can create different types.特别是在使用可以创建不同类型的 avro 或 json 解串器时。

That said, your bean is called importDecisionMessageKafkaListenerContainerFactory .也就是说,您的 bean 称为importDecisionMessageKafkaListenerContainerFactory For listeners to use a non-standard factory, it's name must be specified in the containerFactory property on the listener;对于使用非标准工厂的监听器,它的名称必须在监听器的containerFactory属性中指定; otherwise kafkaListenerContainerFactory is used.否则使用kafkaListenerContainerFactory

This works only in your case because the deserializer is able to deserialize String to both objects.这仅适用于您的情况,因为反序列化器能够将 String 反序列化为两个对象。 But imagine you use Avro and you still have both Pojo1 and Pojo2.但是假设您使用 Avro,但您仍然拥有 Pojo1 和 Pojo2。 In this case you would need two container factories.在这种情况下,您需要两个容器工厂。 If you do not provide one for Pojo2 an exception will be thrown - MessageConversionException: cannot convert String to Pojo2 for GenericMessage .如果您没有为 Pojo2 提供一个异常,则会引发异常 - MessageConversionException: cannot convert String to Pojo2 for GenericMessage The solution would be to define @kafkaListener (topics="topic2", containerFactory="factoryForTopic2")解决方案是定义@kafkaListener (topics="topic2", containerFactory="factoryForTopic2")

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

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