是否可以同时具有侦听器和容器错误处理程序

时间:2019-03-05 11:24:58

标签: spring-kafka

我正在为团队构建一个通用的spring-kafka配置,供团队在其项目中使用。

我想在容器级别定义一个通用的自定义错误处理程序,并允许项目为每个侦听器定义一个侦听器错误处理程序。侦听器错误处理程序未处理的所有内容都应退回到容器中。

从到目前为止的测试来看,它要么是另一个,要么是另一个。有什么办法让他们一起工作?

在容器级别具有一个处理程序链并允许项目向该链中添加错误处理程序是否有意义?

1 个答案:

答案 0 :(得分:0)

没有什么可以阻止您同时配置两个错误处理程序...

@SpringBootApplication
public class So55001718Application {

    public static void main(String[] args) {
        SpringApplication.run(So55001718Application.class, args);
    }

    @KafkaListener(id = "so55001718", topics = "so55001718", errorHandler = "listenerEH")
    public void listen(String in) {
        System.out.println(in);
        if ("bad1".equals(in)) {
            throw new IllegalStateException();
        }
        else if("bad2".equals(in)) {
            throw new IllegalArgumentException();
        }
    }

    @Bean
    public KafkaListenerErrorHandler listenerEH() {
        return (m, t) -> {
            if (t.getCause() instanceof IllegalStateException) {
                System.out.println(
                        t.getClass().getSimpleName() + " bad record " + m.getPayload() + " handled by listener EH");
                return null;
            }
            else {
                throw (t);
            }
        };
    }

    @Bean
    public ConcurrentKafkaListenerContainerFactory<?, ?> kafkaListenerContainerFactory(
            ConcurrentKafkaListenerContainerFactoryConfigurer configurer,
            ConsumerFactory<Object, Object> kafkaConsumerFactory) {

        ConcurrentKafkaListenerContainerFactory<Object, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
        configurer.configure(factory, kafkaConsumerFactory);
        factory.setErrorHandler((t, r) -> {
            System.out.println(t.getClass().getSimpleName() + " bad record " + r.value() + " handled by container EH");
        });
        return factory;
    }

    @Bean
    public NewTopic topic() {
        return new NewTopic("so55001718", 1, (short) 1);
    }

    @Bean
    public ApplicationRunner runner(KafkaTemplate<String, String> template) {
        return args -> {
            template.send("so55001718", "good");
            template.send("so55001718", "bad1");
            template.send("so55001718", "bad2");
        };
    }
}

good
bad1
ListenerExecutionFailedException bad record bad1 handled by listener EH
bad2
ListenerExecutionFailedException bad record bad2 handled by container EH

您可以创建一个简单的包装器来包装多个错误处理程序;随时打开GitHub issue(欢迎捐款)。