为什么没有调用ListenerContainerIdleEvent的eventHandlers?

时间:2018-04-18 01:56:43

标签: spring-kafka

我已在我的应用配置中配置了2个侦听器。

@Bean
public ConsumerFactory<String, String> consumerFactoryForReceiveEvent() {
    Map<String, Object> props = kafkaProps();
    props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "<server 1>");
    return new DefaultKafkaConsumerFactory<>(props);
}

@Bean
public ConsumerFactory<String, String> consumerFactoryForPutawayEvent() {
    Map<String, Object> props = kafkaProps();
    props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "<server 2>");
    return new DefaultKafkaConsumerFactory<>(props);
}

@Bean
public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactoryForReceiveEvent() {
    ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConsumerFactory(consumerFactoryForReceiveEvent());
    factory.setConcurrency(1);
    factory.getContainerProperties().setAckOnError(false);
    factory.getContainerProperties().setErrorHandler(new SeekToCurrentErrorHandler());
    factory.getContainerProperties().setIdleEventInterval(Long.valueOf(30000L);
    factory.getContainerProperties().setAckMode(AbstractMessageListenerContainer.AckMode.MANUAL);
    return factory;
}

@Bean
public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactoryForPutawayEvent() {
    ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConsumerFactory(consumerFactoryForPutawayEvent());
    factory.setConcurrency(1);
    factory.getContainerProperties().setAckOnError(false);
    factory.getContainerProperties().setErrorHandler(new SeekToCurrentErrorHandler());
    factory.getContainerProperties().setIdleEventInterval(30000L);
    factory.getContainerProperties().setAckMode(AbstractMessageListenerContainer.AckMode.MANUAL);
    return factory;
}

为了让我的应用程序启动,我不得不关闭kafka自动配置。当发布消息时,它们会被读取,所以我确信这两个监听器正在工作。但是,当没有发布消息时,不会调用ListenerContainerIdleEvent的eventHandlers。什么可能阻止这些eventHandler被调用?

@EventListener
public void eventHandler(ListenerContainerIdleEvent event) {
    LOG.info("No messages received for " + event.getIdleTime() + " milliseconds");
}

2 个答案:

答案 0 :(得分:0)

您使用的是哪个版本?您的事件监听器在哪里定义?我刚用2.1.5进行测试,一切正常......

@SpringBootApplication
public class So49889974Application {

    private static final Log logger = LogFactory.getLog(So49889974Application.class);

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

    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory(
            ConsumerFactory<String, String> consumerFactory) {
        ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory);
        factory.setConcurrency(1);
        factory.getContainerProperties().setAckOnError(false);
        factory.getContainerProperties().setErrorHandler(new SeekToCurrentErrorHandler());
        factory.getContainerProperties().setIdleEventInterval(30000L);
        factory.getContainerProperties().setAckMode(AbstractMessageListenerContainer.AckMode.MANUAL);
        return factory;
    }

    @KafkaListener(id="foo", topics = "so49889974")
    public void listen(String in) {

    }

    @EventListener
    public void eventHandler(ListenerContainerIdleEvent event) {
        logger.info(event);
    }

}

2018-04-18 10:39:04.238  INFO 92080 --- [      foo-0-C-1] o.s.k.l.KafkaMessageListenerContainer    : partitions assigned: [so49889974-0]
2018-04-18 10:39:31.339  INFO 92080 --- [      foo-0-C-1] com.example.So49889974Application        : ListenerContainerIdleEvent [idleTime=30.242s, listenerId=foo-0, container=KafkaMessageListenerContainer [id=foo-0, clientIndex=-0, topicPartitions=[so49889974-0]], paused=false, topicPartitions=[so49889974-0]]
2018-04-18 10:40:01.451  INFO 92080 --- [      foo-0-C-1] com.example.So49889974Application        : ListenerContainerIdleEvent [idleTime=60.354s, listenerId=foo-0, container=KafkaMessageListenerContainer [id=foo-0, clientIndex=-0, topicPartitions=[so49889974-0]], paused=false, topicPartitions=[so49889974-0]]

答案 1 :(得分:0)

我刚刚遇到了这个问题,我相信原始代码中未触发任何事件的原因如下:

https://github.com/spring-projects/spring-kafka/blob/master/spring-kafka/src/main/java/org/springframework/kafka/listener/ConcurrentMessageListenerContainer.java,它仅发布应用程序事件的一小部分(不发布“ ListenerContainerIdleEvent”事件)。

https://github.com/spring-projects/spring-kafka/blob/master/spring-kafka/src/main/java/org/springframework/kafka/listener/KafkaMessageListenerContainer.java发布这些事件。

使用@KafkaListener默认为KafkaMessageListenerContainer,这就是为什么这些事件在Gary的示例中起作用的原因。