Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring Kafka错误处理程序如何避免无休止的循环_Java_Spring_Apache Kafka_Spring Kafka - Fatal编程技术网

Java Spring Kafka错误处理程序如何避免无休止的循环

Java Spring Kafka错误处理程序如何避免无休止的循环,java,spring,apache-kafka,spring-kafka,Java,Spring,Apache Kafka,Spring Kafka,我希望有人能给我一个暗示,我在这里做错了。我为批处理侦听器编写了一个自定义错误处理程序,该侦听器应该在接收到的记录后面查找,并将它们发送到dlq。我累了很多,但没能使它工作。我当前的实现将挂在一个无休止的循环中,反复接收记录。下面是错误处理程序代码: @Service("consumerAwareListenerErrorHandlerImpl") public class ConsumerAwareListenerErrorHandlerImpl implements ConsumerAwar

我希望有人能给我一个暗示,我在这里做错了。我为批处理侦听器编写了一个自定义错误处理程序,该侦听器应该在接收到的记录后面查找,并将它们发送到dlq。我累了很多,但没能使它工作。我当前的实现将挂在一个无休止的循环中,反复接收记录。下面是错误处理程序代码:

@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,如果它与目标数据兼容,则可以毫无例外地对其进行反序列化。你有什么提示可以告诉我如何解决这个问题吗?