简体   繁体   English

Spring Kafka Consumer 如何跳过 Avro Deserializer 异常

[英]How Spring Kafka Consumer skips from Avro Deserializer exception

I am using Spring Kafka consumer and Avro schema to build my application.我正在使用 Spring Kafka 消费者和 Avro 模式来构建我的应用程序。

However, if the message can't be deserializer to the specified Avro specific record I build, the consumer will keep retrying to consumer same message over and over again (infinite retry).但是,如果消息无法反序列化为我构建的指定 Avro 特定记录,则消费者将一遍又一遍地重试消费者相同的消息(无限重试)。

For this case, how can I configure the consumer application to skip the current message and move to the next offset if there is deserializer exception occurs for my consumer.对于这种情况,如果我的消费者发生反序列化器异常,我如何配置消费者应用程序以跳过当前消息并移动到下一个偏移量。

I have looked at Spring Kafka error handle which can only handle exceptions in the listener not during the deserialization stage.我看过 Spring Kafka 错误句柄,它只能处理侦听器中的异常,而不是在反序列化阶段。

My consumer application is very simple:我的消费者应用程序非常简单:

@KafkaListener(id = "demo-consumer-stream-group", topics = "customer-output-")
  public void process(ConsumerRecord<String, Customer> record) {
    LOGGER.info("Customer key: {} and value: {}", record.key(), record.value());
    LOGGER.info("topic: {}, partition: {}, offset: {}", record.topic(), record.partition(), record.offset());
  }

Base on this code, sometimes the received message may not deserialized to the correct Customer object.基于此代码,有时收到的消息可能不会反序列化为正确的Customer对象。

Also, I saw a recent solution is using ErrorHandlingDeserializer2 of Spring Kafka to handle this, but since I am using KafkaAvroDeserializer how can I work out those configs?另外,我看到最近的一个解决方案是使用 Spring Kafka 的ErrorHandlingDeserializer2来处理这个问题,但是由于我使用的是KafkaAvroDeserializer ,我KafkaAvroDeserializer如何解决这些配置? My current config is:我目前的配置是:

props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, KafkaAvroDeserializer.class);

It's explained in the documentation . 在文档中对此进行了说明

You set the deserializer to the error handling deserializer and its delegate via the custom Spring property. 您可以通过自定义Spring属性将反序列化器设置为错误处理反序列化器及其委托。

You can use the DefaultKafkaConsumerFactory constructor that takes key and value Deserializer objects and wire in appropriate ErrorHandlingDeserializer2 instances that you have configured with the proper delegates. 您可以使用DefaultKafkaConsumerFactory构造函数,该构造函数接受键和值Deserializer对象,并在已使用适当的委托配置的相应ErrorHandlingDeserializer2实例中进行连接。 Alternatively, you can use consumer configuration properties (which are used by the ErrorHandlingDeserializer) to instantiate the delegates. 或者,您可以使用使用者配置属性(由ErrorHandlingDeserializer使用)实例化委托。 The property names are ErrorHandlingDeserializer2.KEY_DESERIALIZER_CLASS and ErrorHandlingDeserializer2.VALUE_DESERIALIZER_CLASS. 属性名称为ErrorHandlingDeserializer2.KEY_DESERIALIZER_CLASS和ErrorHandlingDeserializer2.VALUE_DESERIALIZER_CLASS。 The property value can be a class or class name. 该属性值可以是类或类名称。 The following example shows how to set these properties: 下面的示例显示如何设置这些属性:

... // other props
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, ErrorHandlingDeserializer2.class);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, ErrorHandlingDeserializer2.class);
props.put(ErrorHandlingDeserializer.KEY_DESERIALIZER_CLASS, JsonDeserializer.class);
props.put(JsonDeserializer.KEY_DEFAULT_TYPE, "com.example.MyKey")
props.put(ErrorHandlingDeserializer.VALUE_DESERIALIZER_CLASS, JsonDeserializer.class.getName());
props.put(JsonDeserializer.VALUE_DEFAULT_TYPE, "com.example.MyValue")
props.put(JsonDeserializer.TRUSTED_PACKAGES, "com.example")
return new DefaultKafkaConsumerFactory<>(props);

You need to set your current value + key deserializer both to ErrorHandlingDeserializer.class and the the current value + key deserializer to the ErrorHandlingDeserializer Key/Value deserializer properties您需要将当前值 + 键解串器都设置为 ErrorHandlingDeserializer.class 并将当前值 + 键解串器设置为 ErrorHandlingDeserializer 键/值解串器属性

This will look similar to something like that:这将类似于以下内容:

... // other props
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, ErrorHandlingDeserializer.class);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, ErrorHandlingDeserializer.class);
props.put(ErrorHandlingDeserializer.KEY_DESERIALIZER_CLASS, KafkaAvroDeserializer.class);
props.put(ErrorHandlingDeserializer.VALUE_DESERIALIZER_CLASS, StringDeserializer.class);
return new DefaultKafkaConsumerFactory<>(props);

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

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