简体   繁体   English

Kafka 和具有多种消息类型的主题(Avro):Consumer(spring cloud spring 由于类路径上缺少 class 而失败

[英]Kafka and Topic with Multiple Messages Types (Avro) : Consumer(spring cloud spring fails due to the lack of class on classpath

Topic contains two types of messages: PaymentStarted and PaymentCompleted.主题包含两种类型的消息:PaymentStarted 和 PaymentCompleted。 There are 2 separated microservices with consumers.有 2 个带有消费者的独立微服务。 So:Microservice_1, has consumer1 which should grab the PaymentStarted type;所以:Microservice_1,有 consumer1 应该获取 PaymentStarted 类型; Microservice_2, has consumer2 which should grab the PaymentCompleted type. Microservice_2,有 consumer2 应该获取 PaymentCompleted 类型。 Additionally Microservice_1 contains only PaymentStarted on its jvm classpath and Microservice_2 contains only PaymentCompleted on its jvm classpath.此外,Microservice_1 在其 jvm 类路径中仅包含 PaymentStarted,而 Microservice_2 在其 jvm 类路径中仅包含 PaymentCompleted。

Each service for handling different types of messages.每个服务用于处理不同类型的消息。 I am using spring-cloud-stream, so in my Microservice_1 the Consumer 1 has:我正在使用 spring-cloud-stream,因此在我的 Microservice_1 中,Consumer 1 具有:

@StreamListener(target = PayBindings.EVENTS, condition = "headers['eventType']=='com.company.domain.PaymentStarted'")
    void onPaymentEvents(Message<PaymentStarted> message){
    }

analogically Microservice_2 the Consumer 2 has:类比 Microservice_2 消费者 2 有:

@StreamListener(target = PayBindings.EVENTS, condition = "headers['eventType']=='com.company.domain.PaymentCompleted'")
    void onPaymentEvents(Message<PaymentCompleted> message){
    }

Documentations says( https://cloud.spring.io/spring-cloud-static/spring-cloud-stream/3.0.0.M1/spring-cloud-stream.html#_using_streamlistener_annotation ) that filtering goes before the serialization.文档说( https://cloud.spring.io/spring-cloud-static/spring-cloud-stream/3.0.0.M1/spring-cloud-stream.html#_using_streamlistener_annotation )过滤在序列化之前进行。

But in my case before condition filters them out, the default deserialiser(in my case io.confluent.kafka.serializers.KafkaAvroDeserializer) fails due to lack of PaymentCompleted on the classpath at microservice_1.但在我的情况下,在条件过滤掉它们之前,默认的反序列化器(在我的情况下是 io.confluent.kafka.serializers.KafkaAvroDeserializer)由于 microservice_1 的类路径上缺少 PaymentCompleted 而失败。 Analogically with microservice_2 and PaymentStarted.与 microservice_2 和 PaymentStarted 类比。 I don't want to mix the domains and keep PaymentStarted and PaymentCompleted pojos in Microservice_1 and Microservice_2.我不想混合域并将 PaymentStarted 和 PaymentCompleted pojos 保留在 Microservice_1 和 Microservice_2 中。

I tried to solve that with my custom deserializer and it looks that it is doable with handling exception, but it is really tricky.我试图用我的自定义反序列化器来解决这个问题,看起来它可以处理异常,但这真的很棘手。

I am also confused that the doc I mentioned here above says that the filtering out goes before deserializing.我也很困惑,我上面提到的文档说过滤是在反序列化之前进行的。

I appreciate your thoughts/comments.感谢您的想法/评论。

You should really use a different topic for each type.你真的应该为每种类型使用不同的主题。

However, see Spring for Apache Kafka's ErrorHandlingDeserializer2 .但是,请参阅Spring 了解 Apache Kafka 的 ErrorHandlingDeserializer2

Which will catch the exception and the listener container will route the error directly to the container's error handler.它将捕获异常,并且侦听器容器会将错误直接路由到容器的错误处理程序。

I am also confused that the doc I mentioned here above says that the filtering out goes before deserializing.我也很困惑,我上面提到的文档说过滤是在反序列化之前进行的。

That does not apply when you are using native deserialization, which is much lower down in the stack.当您使用本机反序列化时,这并不适用,它在堆栈中的位置要低得多。

You should consume all messages and inside the function onPaymentEvents filter messages needed be each consumer.您应该使用所有消息,并且在 function onPaymentEvents过滤器消息中需要每个消费者。 I suppose you have a single microservice that producer both type of messages.Also I replace the Avro with JSON.我想你有一个产生两种类型消息的微服务。另外我用 JSON 替换了 Avro。

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

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