Spring Kafka listenerExecutor

Viewed 3429

I'm setting up a kafka listener in a spring boot application and I can't seem to get the listener running in a pool using an executor. Here's my kafka configuration:

@Bean
ThreadPoolTaskExecutor messageProcessorExecutor() {
    logger.info("Creating a message processor pool with {} threads", numThreads);
    ThreadPoolTaskExecutor exec = new ThreadPoolTaskExecutor();
    exec.setCorePoolSize(200);
    exec.setMaxPoolSize(200);
    exec.setKeepAliveSeconds(30);
    exec.setAllowCoreThreadTimeOut(true);
    exec.setQueueCapacity(0); // Yields a SynchronousQueue
    exec.setThreadFactory(ThreadFactoryFactory.defaultNamingFactory("kafka", "processor"));
    return exec;
}

@Bean
public ConsumerFactory<String, PollerJob> consumerFactory() {
    Map<String, Object> props = new HashMap<>();
    props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
    props.put(ConsumerConfig.GROUP_ID_CONFIG, consumerGroup);
    props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
    DefaultKafkaConsumerFactory<String, PollerJob> factory = new DefaultKafkaConsumerFactory<>(props,
            new StringDeserializer(),
            new JsonDeserializer<>(PollerJob.class));
    return factory;
}

@Bean
public ConcurrentKafkaListenerContainerFactory<String, PollerJob> kafkaListenerContainerFactory() {
    ConcurrentKafkaListenerContainerFactory<String, PollerJob> factory
            = new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConsumerFactory(consumerFactory());
    factory.setConcurrency(Integer.valueOf(kafkaThreads));
    factory.getContainerProperties().setListenerTaskExecutor(messageProcessorExecutor());
    factory.getContainerProperties().setAckMode(AbstractMessageListenerContainer.AckMode.MANUAL);
    return factory;
}

The ThreadFactoryFactory used by the ThreadPoolTaskExecutor just makes sure the thread is named like 'kafka-1-processor-1'.

The ConsumerFactory has the ENABLE_AUTO_COMMIT_CONFIG flag set to false and I'm using manual mode for the acknowledgement which is required to use executors according to the documentation.

My listener looks like this:

@KafkaListener(topics = "my_topic",
        group = "my_group",
        containerFactory = "kafkaListenerContainerFactory")
public void listen(@Payload SomeJob job, Acknowledgment ack) {
    ack.acknowledge();
    logger.info("Running job {}", job.getId());
    ....
}

Using the Admin Server I can inspect all the threads and only one kafka-N-processor-N threads is being created but I expected to see up to 200. The jobs are all running one at a time on the that one thread and I can't figure out why.

How can I get this setup to run the listeners using my executor with as many threads as possible?

I'm using Spring Boot 1.5.4.RELEASE and kafka 0.11.0.0.

1 Answers
Related