60-Day Kafka 4 Learning Plan · Week 1 — Day 4 of 60


60-Day Kafka 4 Learning Plan · Week 1 — Foundations · Spring Boot Lab
Sources:
Kafka: The Definitive Guide Ch.2 · kafka.apache.org/43 — Quick Start


Goal

Run Kafka 4 locally in KRaft mode + wire a Spring Boot 3 app in under 15 minutes.

1. Prerequisites

2. docker-compose.yml — Kafka 4 KRaft

services:
kafka:
image: confluentinc/cp-kafka:7.9.0
hostname: kafka
container_name: kafka
ports:
- "9092:9092" # client connections (Spring Boot)
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller # combined mode (dev only)
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk # generate: kafka-storage.sh random-uuid
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

Key env vars explained:

VariablePurposeKAFKA_PROCESS_ROLES=broker,controllerCombined mode — OK for dev, use separate roles in productionKAFKA_CONTROLLER_QUORUM_VOTERSKRaft quorum members: nodeId@host:controllerPortCLUSTER_IDStable UUID — generate once with kafka-storage.sh random-uuidKAFKA_ADVERTISED_LISTENERSAddress Spring Boot (and other clients) use to connect

Add to the same docker-compose.yml:

kafka-ui:
image: provectuslabs/kafka-ui:latest
ports:
- "8090:8080"
environment:
KAFKA_CLUSTERS_0_NAME: local-kafka4
KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:9092

Access at http://localhost:8090 — browse topics, partitions, messages, consumer lag in real time.

4. Spring Boot 3.x — pom.xml dependency

<dependencies>
<!-- Spring Kafka (auto-configures KafkaTemplate + @KafkaListener) -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<!-- version managed by Spring Boot BOM — no version tag needed -->
</dependency>
</dependencies>

5. application.yml — Spring Kafka config

spring:
kafka:
bootstrap-servers: localhost:9092
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
consumer:
group-id: boottech-consumer-group
auto-offset-reset: earliest
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer

6. Minimal Spring Boot wiring — smoke test

// --- Producer ---
@Service
public class KafkaProducerService {

@Autowired
private KafkaTemplate<String, String> kafkaTemplate;

public void send(String topic, String message) {
kafkaTemplate.send(topic, message);
}
}

// --- Consumer ---
@Component
public class KafkaConsumerListener {

@KafkaListener(topics = "boottech-topic", groupId = "boottech-consumer-group")
public void listen(String message) {
System.out.println("Received: " + message);
}
}

7. Start & verify — 4 steps

# 1. Start the cluster
docker compose up -d
# Wait ~10 seconds for Kafka to initialize

# 2. Check health
docker compose ps
# All services should show: healthy

# 3. Create the topic
docker exec kafka kafka-topics.sh \
--create \
--topic boottech-topic \
--partitions 3 \
--replication-factor 1 \
--bootstrap-server localhost:9092

# 4. Run Spring Boot
mvn spring-boot:run
# Watch the console — @KafkaListener will log received messages

Full local architecture

Spring Boot App          Kafka 4 KRaft           Kafka UI
localhost:8080 ──9092──► Docker:9092 ──8090──► localhost:8090

TL;DR

  • Copy the docker-compose.yml,
  • run docker compose up -d,
  • add spring-kafka to pom.xml,
  • set bootstrap-servers: localhost:9092 in application.yml,
  • inject KafkaTemplate to produce,
  • use @KafkaListener to consume — Kafka 4 KRaft is running in under 15 minutes.

Support me through GitHub Sponsors.

Next

➡️ Day 5 — Producers in depth: KafkaTemplate, acks, retries, idempotence, partitioning strategies

Resources

👉 Link to Medium blog

Related Posts