A high-performance Spring Boot application that provides REST API access to Kafka messages with rack-aware optimization and connection pooling.
- 100% Kafka REST Proxy Compatible - Identical response format and field ordering
- Follower message fetching for optimized network performance
- Connection pooling with pre-allocated consumers and producers
- Async processing for high throughput operations
- External configuration support via ER properties
- Real-time monitoring of connection pools
- Message production with batch optimization
- Performance tuning based on ER Kafka REST configurations
GET /topics/{topic}/partitions/{partition}/messages
Parameters:
offset(required): Starting offset to read fromcount(optional): Number of messages to retrieve (default: 10, max: 1000)clientRack(optional): Preferred rack for rack-aware fetching
Example:
curl "http://localhost:8080/topics/my-topic/partitions/0/messages?offset=100&count=5&clientRack=zone-a"POST /topics/{topic}
Parameters:
clientRack(optional): Rack preference for producer optimization
Request Body:
{
"records": [
{
"key": "message-key",
"value": "message content",
"partition": 0
}
]
}Example:
curl -X POST "http://localhost:8080/topics/my-topic" \
-H "Content-Type: application/json" \
-d '{
"records": [
{
"key": "user-123",
"value": "Hello Kafka!",
"partition": 0
}
]
}'GET /topics/{topic}/partitions/{partition}/offsets
Parameters:
clientRack(optional): Rack preference for optimization
Response:
{
"beginning_offset": 0,
"end_offset": 1234
}GET /monitoring/pool-stats
Returns connection pool statistics and health information.
# Compile and run with built-in settings
mvn clean package -DskipTests
java -jar target/kafka-offset-reader-1.0.0.jarUses configuration from etc/kafka-rest/er-kafka-rest.properties
# Run with external properties file
java -jar target/kafka-offset-reader-1.0.0.jar /path/to/your/config.propertiesExample with relative path:
# Place config file relative to JAR location
java -jar target/kafka-offset-reader-1.0.0.jar .\etc\kafka-rest\er-kafka-rest.propertiesExample with absolute path:
# Use absolute path to config file
java -jar target/kafka-offset-reader-1.0.0.jar C:\kafka-configs\production.properties# Compile
mvn initialize
mvn clean compile
# Run in development
mvn spring-boot:run- 15 pre-allocated consumers per rack for instant message retrieval
- Producer pooling with rack-aware routing
- Optimized fetch settings from ER configuration
- Async thread pool (10-50 threads) for concurrent operations
- Connection reuse to minimize TCP overhead
This application significantly outperforms the standard Kafka REST Proxy through:
- Rack-aware optimization: Consumers fetch from same-rack brokers
- Connection pooling: Eliminates connection setup overhead
- ER configuration: Uses enterprise-grade Kafka settings
- Async processing: Non-blocking operations for high throughput
- Producer efficiency: Batching and rack-aware message routing
- Reduced latency - Read from local replicas
- Lower network costs - Avoid cross-zone traffic
- Better load distribution - Spread load across brokers
- High availability - Automatic failover to other racks
The application provides detailed logging showing rack-aware behavior:
2025-01-09 12:15:23 INFO - External configuration loaded: kafka.client.rack=zone-b
2025-01-09 12:15:30 INFO - Reading from topic: test-topic, partition: 0, rack: zone-b
2025-01-09 12:15:30 DEBUG - Consumer created with rack preference: zone-b
2025-01-09 12:15:30 DEBUG - Kafka client attempting connection to zone-b broker first
2025-01-09 12:15:30 INFO - Successfully read 3 messages from rack zone-b
2025-01-09 12:15:31 DEBUG - Connection pattern: zone-b (preferred) -> zone-a (failover)
The application supports a comprehensive configuration hierarchy for production deployment flexibility:
- Runtime Override (Highest Priority) - Via REST API parameters
- External Configuration -
etc/kafka-rest/er-kafka-rest.properties(relative to JAR) - Application Properties -
src/main/resources/application.properties - Default Values (Lowest Priority) - Hardcoded fallbacks
For production deployment, create an external configuration file:
File Location: etc/kafka-rest/er-kafka-rest.properties (relative to JAR file)
# Kafka Connection Configuration
kafka.bootstrap.servers=prod-kafka-1:9092,prod-kafka-2:9092,prod-kafka-3:9092
kafka.client.dns.lookup=use_all_dns_ips
kafka.client.timeout.ms=30000
kafka.client.request.timeout.ms=60000
# Rack-Aware Configuration
kafka.client.rack=zone-b
# Consumer Configuration
kafka.consumer.group.id=kafka-offset-reader
kafka.consumer.auto.offset.reset=earliest
kafka.consumer.enable.auto.commit=false
# Connection Pool Settings
kafka.consumer.max.poll.records=500
kafka.consumer.session.timeout.ms=30000
kafka.consumer.heartbeat.interval.ms=3000
# Security Configuration (if needed)
# kafka.security.protocol=SASL_SSL
# kafka.sasl.mechanism=PLAIN
# kafka.sasl.jaas.config=...Default configuration in src/main/resources/application.properties:
# Server Configuration
server.port=8080
# Kafka Cluster Connection (Development)
kafka.bootstrap.servers=localhost:9092, localhost:9094, localhost:9096
kafka.client.dns.lookup=use_all_dns_ips
# Rack-Aware Follower Fetching Configuration
kafka.client.rack=zone-c
# Enable debug logging
logging.level.org.apache.kafka.clients.consumer=DEBUGOverride any configuration per request using REST API parameters:
# Override rack selection to zone-a
curl "http://localhost:8080/topics/test-topic/partitions/0/messages?offset=0&count=3&clientRack=zone-a"
# Override rack selection to zone-b
curl "http://localhost:8080/topics/test-topic/partitions/0/messages?offset=0&count=3&clientRack=zone-b"
# Use configured default (external config → application.properties → zone-c)
curl "http://localhost:8080/topics/test-topic/partitions/0/messages?offset=0&count=3"The application logs the configuration hierarchy at startup:
2025-01-09 10:15:23 INFO - External configuration loaded from: /opt/kafka-services/etc/kafka-rest/er-kafka-rest.properties
2025-01-09 10:15:23 INFO - Configuration hierarchy: Runtime → External → Application → Defaults
2025-01-09 10:15:23 INFO - Active kafka.client.rack: zone-b (source: external)
2025-01-09 10:15:23 INFO - Active kafka.bootstrap.servers: prod-kafka-1:9092,prod-kafka-2:9092,prod-kafka-3:9092 (source: external)
This project uses a patched Kafka client (kafka-clients-4.2.0-follower-fetch.jar) that adds:
client.rackproperty: Specifies which rack the client belongs to for rack-aware replica selection- Runtime override capability: Allows changing rack selection per consumer
- Enhanced logging: Shows which rack is being used for consumption
The pom.xml includes an automatic installation plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-patched-kafka</id>
<phase>validate</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<file>lib/kafka-clients-4.2.0-follower-fetch.jar</file>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>4.2.0-follower-fetch</version>
<packaging>jar</packaging>
</configuration>
</execution>
</executions>
</plugin>This ensures the patched JAR is automatically installed to your local Maven repository during the build process.
kafka-offset-reader/
├── lib/
│ └── kafka-clients-4.2.0-follower-fetch.jar # Patched Kafka client for rack-aware fetching
├── src/main/java/com/example/kafkaoffsetreader/
│ ├── KafkaOffsetReaderApplication.java # Spring Boot main class with async configuration
│ ├── KafkaReaderController.java # REST API endpoints (GET/POST/monitoring)
│ ├── KafkaReaderService.java # Kafka read operations with connection pooling
│ ├── KafkaProducerService.java # Kafka producer service with rack-aware routing
│ ├── KafkaConnectionPool.java # Connection pooling for high-performance consumers
├── src/main/resources/
│ └── application.properties # Default application configuration
├── etc/kafka-rest/
│ └── er-kafka-rest.properties # External configuration
├── target/
│ ├── classes/ # Compiled Java classes
│ └── kafka-offset-reader-*.jar # Built application JAR
├── pom.xml # Maven configuration with patched Kafka dependency
├── README.md # Complete documentation