消费者重试完成后,春季Kafka产生消息

时间:2020-07-13 13:51:02

标签: spring-boot apache-kafka spring-kafka

我有一个kafka使用者,它使用主题中的消息并进行处理。我已应用5的重试尝试来处理该消息,并将该消息写入另一个主题,以备将来参考,以防万一即使5次尝试后处理仍失败。我的代码如下:

KafkaConsumerConfig:

   @Bean
    KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<Object, Object>> kafkaManualAckListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<Object, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        factory.setConcurrency(Integer.parseInt(kafkaConcurrency));
        factory.setErrorHandler(new SeekToCurrentErrorHandler(null, 5));
        return factory;
    }

KafkaConsumer:

    @Value("${kafka.consumer.failed.topic}")
    private String failedTopic;
    
    @KafkaListener(topics = "${kafka.consumer.topic}", groupId = "${kafka.consumer.groupId}", containerFactory = "kafkaManualAckListenerContainerFactory")
    public void processMessage(String kafkaMessage) throws Exception {
        log.info("parsing new kafka message {}", kafkaMessage);
        TransactionDTO transactionDTO = TransformUtil.fromJson(kafkaMessage, TransactionDTO.class);
        try {
            service.parseTransactionDTO(transactionDTO);
        } catch (Exception e) {
            log.error(e.getMessage());
            kafkaTemplate.send(failedTopic, kafkaMessage);
            Thread.sleep(10000);
            throw e;
        }
    }

消费者正确地尝试进行5次尝试,延迟10秒,但是每次失败,都会向失败的主题中写入一条新消息。有没有办法在所有重试尝试都用完之后,仅将消息写入失败主题一次,而不是每次失败都将其写入失败主题?

1 个答案:

答案 0 :(得分:0)

factory.setErrorHandler(new SeekToCurrentErrorHandler(null, 5));

在错误处理程序中使用DeadLetterPublishingRecoverer代替null

它是在2.2中引入的;我不确定您使用的是哪个版本。如果版本较旧,则可以升级(当前版本为2.5.3),也可以将发布代码移至自定义恢复器中。

较新版本(从2.3版开始)允许在重试尝试之间添加退避延迟。