Spring Framework
Kafka Consumer
Listener Group
Message Brokering
Distributed Systems

Spring Kafka Consumer/Listener Group

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Apache Kafka is a powerful, distributed messaging system that enables applications to process and retransmit stream data efficiently. In real-world applications, it is often necessary to consume messages from a Kafka topic with multiple consumers grouped together for scalability and fault tolerance. Spring Kafka provides sophisticated support to configure and manage Kafka consumers in a listener group.

Understanding Consumer Groups

A consumer group is a set of consumers which jointly consume the data from one or more topics. The consumers in a group can be running in separate processes or on separate machines. Kafka ensures that each partition of a topic is only consumed by one consumer in the group, thereby enabling the consumers to jointly parallelize the data processing. If one consumer in the group fails, Kafka redistributes the partitions among the remaining consumers.

Configuration of Spring Kafka Consumer Groups

To implement a Kafka consumer group using Spring Kafka, the @KafkaListener annotation is typically used. This annotation allows you to easily create listeners for any topics. The basic properties to configure a consumer are groupId, topics, and the concurrency settings.

Here's a basic example in a Spring Boot application:

java
1@Service
2public class KafkaConsumerService {
3
4    @KafkaListener(topics = "example_topic", groupId = "example_group")
5    public void listen(String message) {
6        System.out.println("Received message: " + message);
7    }
8}

In this example:

  • @KafkaListener marks the listen method to be the target of a Kafka message listener on the specified topics.
  • groupId specifies the consumer group ID. All consumers with the same group ID are part of the same consumer group.
  • The topics attribute specifies the Kafka topics to listen to.

Handling Different Partitions

You can configure listeners to specifically handle certain partitions of a topic by setting the partitions and partitionOffsets attributes of @KafkaListener.

java
1@KafkaListener(topicPartitions = @TopicPartition(topic = "example_topic",
2                                                 partitions = { "0", "1" },
3                                                 partitionOffsets = @PartitionOffset(partition = "1", initialOffset = "100")))
4public void listenToPartition(@Payload String message, @Header(KafkaHeaders.RECEIVED_PARTITION_ID) int partition) {
5    System.out.println("Received message: " + message + " from partition: " + partition);
6}

Concurrent Message Consumption

To enhance the performance by processing multiple messages concurrently, you can set the concurrency property of the @KafkaListener.

java
1@KafkaListener(topics = "example_topic", groupId = "example_group", concurrency = "3")
2public void concurrentMessageListener(String message) {
3    System.out.println("Received message: " + message);
4}

This sets up three concurrent consumers within the same group.

Error Handling

Spring Kafka provides several mechanisms for handling errors, including the ability to configure a ErrorHandlingDeserializer or use a SeekToCurrentErrorHandler to manage retries.

Summary Table

PropertyDescriptionExample Value
topicsTopics to listen to"example_topic"
groupIdSpecifies consumer group ID"example_group"
concurrencyNo. of concurrent consumers in the listener"3"
partitionsSpecific partitions to consume{ "0", "1" }
initialOffsetOffset to start consuming messages"100"
containerFactorySpecifies which container factory to use"kafkaListenerContainerFactory"

Additional Features in Spring Kafka

  • Batch Listeners: By setting the batch property to true, you can consume messages in batches, increasing throughput under high load.
  • Container Customization: It's possible to customize listener containers for more fine-grained control over thread management, error handling, and message conversion.
  • Transactional Listeners: For scenarios that require exactly-once processing semantics, Spring Kafka supports transactional listeners.

Conclusion

Spring Kafka provides comprehensive support for Kafka's consumer groups, making it easy to implement scalable and fault-tolerant message-consuming services. With annotations and convenient configuration options, developing message-driven applications becomes straightforward and standardized across different projects.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.