Java Spring Kafka错误处理程序如何避免无休止的循环
我希望有人能给我一个暗示,我在这里做错了。我为批处理侦听器编写了一个自定义错误处理程序,该侦听器应该在接收到的记录后面查找,并将它们发送到dlq。我累了很多,但没能使它工作。我当前的实现将挂在一个无休止的循环中,反复接收记录。下面是错误处理程序代码:Java Spring Kafka错误处理程序如何避免无休止的循环,java,spring,apache-kafka,spring-kafka,Java,Spring,Apache Kafka,Spring Kafka,我希望有人能给我一个暗示,我在这里做错了。我为批处理侦听器编写了一个自定义错误处理程序,该侦听器应该在接收到的记录后面查找,并将它们发送到dlq。我累了很多,但没能使它工作。我当前的实现将挂在一个无休止的循环中,反复接收记录。下面是错误处理程序代码: @Service("consumerAwareListenerErrorHandlerImpl") public class ConsumerAwareListenerErrorHandlerImpl implements ConsumerAwar
@Service("consumerAwareListenerErrorHandlerImpl")
public class ConsumerAwareListenerErrorHandlerImpl implements ConsumerAwareListenerErrorHandler {
private final Executor executor;
private final KafkaListenerEndpointRegistry registry;
private final TaskScheduler scheduler;
@Autowired
public ConsumerAwareListenerErrorHandlerImpl(KafkaListenerEndpointRegistry registry, TaskScheduler scheduler) {
this.scheduler = scheduler;
this.executor = new SimpleAsyncTaskExecutor();
this.registry = registry;
}
@Override
public Object handleError(Message<?> message, ListenerExecutionFailedException exception, Consumer<?, ?> consumer) {
MessageHeaders headers = message.getHeaders();
List<String> topics = headers.get(KafkaHeaders.RECEIVED_TOPIC, List.class);
List<Integer> partitions = headers.get(KafkaHeaders.RECEIVED_PARTITION_ID, List.class);
List<Long> offsets = headers.get(KafkaHeaders.OFFSET, List.class);
Acknowledgment acknowledgment = headers.get(KafkaHeaders.ACKNOWLEDGMENT, Acknowledgment.class);
Map<TopicPartition, Long> offsetsToReset = new HashMap<>();
for (int i = 0; i < topics.size(); i++) {
int index = i;
offsetsToReset.compute(new TopicPartition(topics.get(i), partitions.get(i)),
(k, v) -> (v == null) ? offsets.get(index) : Math.max(v, offsets.get(index)));
}
offsetsToReset.forEach((k, v) -> consumer.seek(k, v));
if (!(exception.getCause() instanceof DeserializationException)) {
//pauseAndRestartContainer();
}
acknowledgment.acknowledge();
consumer.commitSync();
return null;
}
你必须设法抵消+1才能通过。寻求偏移将导致它被重放。谢谢您的提示!我还有一个问题,当发生反序列化异常时,不会调用错误hanlde。当然,我可以使用ErrorHandlingDeserializer和手动过滤错误记录,但这对我没有帮助。我尝试:serialization异常:log;寻找过去;继续前进;其他例外情况:暂停;定时重启;再试一次您知道如何解决批处理侦听器的问题吗?我们添加了ErrorHandlingDeserializer2…2比第一个更好,因为正是出于这个原因,它是类型安全的。问题是反序列化异常发生在Spring获取数据之前,因此我们没有其他方法可以做。但我仍然必须像看起来那样在容器中过滤它们?!是,当使用批处理侦听器时;但是,现在更方便了,因为如果提供failedDeserializationFunction,则该值是类型安全的null或伪反序列化对象。当使用基于记录的侦听器时,失败的记录将直接发送到容器的错误处理程序。Gary Russel还有一个问题:如果我使用ErrorHandlingDeserializer2,发送者需要使用相同的类将json发送到我的容器侦听器。否则我将获取org.springframework.messaging.converter.MessageConversionException:解析类名失败。如果我不使用ErrorHandlingDeserializer2,发送方可以发送任何json,如果它与目标数据兼容,则可以毫无例外地对其进行反序列化。你有什么提示可以告诉我如何解决这个问题吗?