There are two implementations of MessageListenerContainer
- the KafkaMessageListenerContainer
(KMLC) and ConcurrentMessageListenerContainer
(CMLC).
The CMLC is simply a wrapper for one or more KMLCs, with the number of KMLCs specified by the concurrency
.
@KafkaListener
always uses a CMLC.
Each KMLC gets one Consumer
(and one thread). The thread continually poll()
s the consumer, with the specified pollTimeout
.
How the topics/partitions are distributed across the KMLCs depends on
- how many partitions the topic(s) have
- the consumer's
partition.assignment.strategy
property
If you have multiple topics with fewer partitions than the concurrency, you will likely need an alternate partition assignor, such as the round robin assignor, otherwise you will have idle containers with no assignment.
- That is correct; if you explicitly want a different container for each topic, you can provide multiple
@KafkaListener
annotations on the same method.
- See my explanation above.
- That is correct - it's the only way to get concurrency with Kafka (without adding very complicated logic to manage offsets).
- The number of records returned by each poll depends on a number of consumer properties,
max.poll.records
, fetch.min.bytes
, fetch.max.wait.ms
.