[英]How to move past undeserializable messages in Spring Kafka 1.3 with Avro
我无法升级到Spring 5,因此无法使用spring-kafka 1.3及其有限的错误处理功能。 所以我无权从spring-kafka 2访问ConsumerAwareErrorHandler或SeekToCurrent错误处理程序。
我正在使用@KafkaListener
方法来侦听主题,我已经将io.confluent.kafka.serializers.KafkaAvroDeserializer
配置为我的值反序列化器。
问题是,如果我最终在主题中收到的消息不是Avro格式,则KafkaMessageListenerContainer轮询循环会卡住。 反序列化器在消息上引发异常,而轮询循环再也找不到它了,因此下一次通过循环,它将尝试反序列化同一条消息并保持循环,每秒将同一个错误几千次转储到我的日志中。
似乎没有办法获得NeverRetryPolicy或其他任何方法,但是我可以factory.getContainerProperties().setErrorHandler()
。 不幸的是,我不确定从那里可以做什么。
是否可以自动连线到错误处理程序中,以便在错误时向前寻找1个偏移量? 不知道那是什么,文档并没有过多地讨论您可以使用ErrorHandler实际执行的操作,而我能找到的大多数示例都是针对spring-kafka 2.X的。 就像,它不会反序列化,没有什么我可以处理的消息,它将永远无法工作,我想避免再试一次,而且似乎大多数Stackoverflow问题都在做相反的事情。
我还看到有些人只是将Avro的Deserializer包装到自己的类中,该类吃掉异常并返回null。 那是一个更好的计划吗?
问题是反序列化在Spring获取数据之前就失败了-问题出在Kafka本身。
在2.2中,我们添加了ErrorHandlingDeserializer2
,它包装了实际的反序列化器,并将信号发送到侦听器容器,以便可以将错误发送到错误处理程序。
在较旧的版本中,您需要编写自己的反序列化程序包装器-但是,容器中没有代码来处理这种情况,因此您的catch块将需要返回一个真实的对象,该对象向侦听器发出信号,表明反序列化失败。
假设您的听众收到Invoice
。 您的catch块可以创建一个子类,例如BadInvoice
,然后您可以在侦听器中检测该子类BadInvoice
其丢弃。
我还看到有些人只是将Avro的Deserializer包装到自己的类中,该类吃掉异常并返回null。 那是一个更好的计划吗?
如果您从未获得真正的空记录,则可以返回null
,但@Payload(required = false)
在方法参数中添加@Payload(required = false)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.