Spring boot 使用spring boot 2.3.7版处理spring kafka消费者批量错误

Spring boot 使用spring boot 2.3.7版处理spring kafka消费者批量错误,spring-boot,spring-kafka,Spring Boot,Spring Kafka,我正在尝试执行spring kafka批处理错误处理。首先,我有几个问题 侦听器和容器错误处理程序之间的区别是什么?这两类错误有哪些 你能不能帮我拿一些样品来了解一下 这是我们的设计: 每隔一段时间投票一次 以批处理模式使用消息 基于密钥推送到本地缓存(应用程序缓存)(以避免重复事件) 批处理完成后,将所有值逐个推送到另一个主题 一旦操作3完成,清除缓存并手动确认偏移 以下是我的错误处理计划: public ConcurrentKafkaListenerContainerFactory<

我正在尝试执行spring kafka批处理错误处理。首先,我有几个问题

  • 侦听器和容器错误处理程序之间的区别是什么?这两类错误有哪些

  • 你能不能帮我拿一些样品来了解一下

  • 这是我们的设计:

  • 每隔一段时间投票一次
  • 以批处理模式使用消息
  • 基于密钥推送到本地缓存(应用程序缓存)(以避免重复事件)
  • 批处理完成后,将所有值逐个推送到另一个主题
  • 一旦操作3完成,清除缓存并手动确认偏移
  • 以下是我的错误处理计划:

    public ConcurrentKafkaListenerContainerFactory<String, String> myListenerPartitionContainerFactory(String groupId) {
            ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
            factory.setConsumerFactory(consumerFactory(groupId));
            factory.setConcurrency(partionCount);
            factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL);
            factory.getContainerProperties().setIdleBetweenPolls(pollInterval);
            factory.setBatchListener(true);
    
            return factory;
        }
    
        @Bean
        public ConcurrentKafkaListenerContainerFactory<String, String> myPartitionsListenerContainerFactory() 
        {
            return myListenerPartitionContainerFactory(groupIdPO);
        }
    
    
    @Bean
    public RecoveringBatchErrorHandler(KafkaTemplate<String, String> errorKafkaTemplate) {
        DeadLetterPublishingRecoverer recoverer =
                new DeadLetterPublishingRecoverer(errorKakfaTemplate);
        RecoveringBatchErrorHandler errorHandler =
                new RecoveringBatchErrorHandler(recoverer, new FixedBackOff(2L, 5000)); // push error event to the error topic
    }
    
    
    @KafkaListener(id = "mylistener", topics = "someTopic", containerFactory = "myPartitionsListenerContainerFactory"))
    public void listen(List<ConsumerRecord<String, String>> records, @Header(KafkaHeaders.MESSAGE_KEY) String key, Acknowledgement ack) {
        Map hashmap = new Hashmap<>();
        records.forEach(record -> {
            try {
                //key will be formed based on the input record - it will be id.
                hashmap.put(key, record);  
            }
            catch (Exception e) {
                throw new BatchListenerFailedException("Failed to process", record);
            }
             
        });
        // Once success each messages to another topic.
        try {
          hashmap.forEach( (key,value) -> {  push to another topic })
          hashmap.clear();
          ack.acknowledge();
        } catch(Exception ex) {
            //handle producer exceptions
        }
    }
    
    public ConcurrentKafkaListenerContainerFactory myListenerPartitionContainerFactory(字符串组ID){
    ConcurrentKafkListenerContainerFactory=新ConcurrentKafkListenerContainerFactory();
    setConsumerFactory(consumerFactory(groupId));
    factory.setConcurrency(partionCount);
    factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL);
    factory.getContainerProperties().SetIdleBeweenPolls(pollInterval);
    factory.setBatchListener(true);
    返回工厂;
    }
    @豆子
    公共ConcurrentKafkaListenerContainerFactory myPartitionsListenerContainerFactory()
    {
    返回myListenerPartitionContainerFactory(groupIdPO);
    }
    @豆子
    公共恢复BatchErrorHandler(KafkaTemplate errorKafkaTemplate){
    死信发布恢复程序恢复程序=
    新死信发布回收器(ErrorKakFatTemplate);
    RecoveringBatchErrorHandler错误处理程序=
    new RecoveringBatchErrorHandler(recoverer,new FixedBackOff(2L,5000));//将错误事件推送到错误主题
    }
    @KafkaListener(id=“mylistener”,topics=“someTopic”,containerFactory=“myPartitionsListenerContainerFactory”))
    public void listen(列表记录,@Header(KafkaHeaders.MESSAGE_键)字符串键,确认确认){
    Map hashmap=新hashmap();
    记录。forEach(记录->{
    试一试{
    //键将根据输入记录形成-它将是id。
    hashmap.put(键,记录);
    }
    捕获(例外e){
    抛出新的BatchListenerFailedException(“处理失败”,记录);
    }
    });
    //一旦成功,每个邮件都会转到另一个主题。
    试一试{
    forEach((键,值)->{push to other topic})
    clear();
    确认();
    }捕获(例外情况除外){
    //处理生产者异常
    }
    }
    
    方向是否正确,或者是否需要进行任何改进?还需要实现什么类型的容器和侦听器处理程序


    @加里·拉塞尔。。您能在这方面提供帮助吗?

    侦听器错误处理程序适用于错误处理程序可以向发件人返回有意义的答复的请求/答复情况

    您需要抛出一个异常来触发容器错误处理程序,并且需要知道原始批处理中的索引中有哪些记录失败

    如果您使用的是这样的手动确认,那么可以使用nack()方法来指示哪个记录失败(在这种情况下不要抛出异常)