Kafka con Spring Boot: guía práctica
Aprende a usar Kafka con Spring Boot: dependencias, configuración, productor con KafkaTemplate y consumidor con @KafkaListener. Con ejemplos de código.

Kafka con Spring Boot: guía práctica
Kafka es un sistema de mensajería distribuido diseñado para publicar y consumir flujos de eventos en tiempo real. Con Spring Boot, la integración se resuelve con spring-kafka y su API KafkaTemplate y @KafkaListener. Los mensajes se organizan en topics, divididos en particiones para escalar de forma horizontal y garantizar el procesamiento ordenado.
Última actualización: agosto 2026
Contenido Rápido
- Kafka es un sistema de mensajería distribuido basado en eventos
spring-kafkaaportaKafkaTemplatepara publicar y@KafkaListenerpara consumir- Los mensajes viven en topics divididos en particiones
- Configuración mínima:
spring.kafka.bootstrap-servers - Serialización JSON con
JsonSerializeryJsonDeserializer - Ideal para microservicios, pipelines de datos y desacoplamiento
Kafka es uno de los sistemas de mensajería más usados en el backend moderno y Spring Boot lo integra de forma casi automática gracias a spring-kafka. En esta guía práctica vas a montar un productor y un consumidor funcionales, con la configuración mínima y ejemplos listos para adaptar a tu proyecto. Si es la primera vez que trabajas con el framework, te recomendamos empezar por qué es Spring Boot y cómo funciona.
Qué es Kafka
Kafka es un broker de mensajería distribuido creado por la fundación Apache y escrito en Java y Scala. A diferencia de una cola clásica, los mensajes no se eliminan cuando un consumidor los lee: quedan persistidos en disco durante un periodo de retención configurable y cada consumidor avanza por el flujo a su propio ritmo. Eso permite que varios sistemas lean el mismo evento sin interferir entre sí. Si quieres profundizar, la introducción oficial de Apache Kafka explica el modelo completo.
Para seguir esta guía solo necesitas cuatro conceptos:
- Topic: la categoría lógica donde se publican los mensajes de un mismo tipo.
- Partición: la subdivisión del topic que aporta orden y paralelismo. Kafka garantiza el orden dentro de cada partición.
- Producer: el componente que publica mensajes en un topic.
- Consumer: el componente que lee los mensajes de las particiones. Varios consumidores con el mismo
group-idse reparten las particiones entre sí.
Añadir spring-kafka al proyecto
Spring Boot gestiona la versión de spring-kafka a través de su BOM, así que en Maven basta con declarar la dependencia sin versionarla:
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
En Gradle la equivalencia es implementation 'org.springframework.kafka:spring-kafka'. Con la dependencia en el classpath, Spring Boot auto-configura las fábricas de productor y consumidor: no necesitas escribir @EnableKafka ni crear beans de ProducerFactory para el caso básico. La documentación de Spring para Apache Kafka detalla todas las opciones disponibles.
Configuración en application.properties
La única propiedad obligatoria es spring.kafka.bootstrap-servers, que indica dónde está tu broker. Para el ejemplo end-to-end con JSON, añade también los serializadores y el group-id del consumidor:
spring.kafka.bootstrap-servers=localhost:9092
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer
spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer
spring.kafka.consumer.group-id=grupo-pedidos
spring.kafka.consumer.auto-offset-reset=earliest
spring.kafka.consumer.properties.spring.json.trusted.packages=*
Si tu broker vive en otra máquina o en un cluster, sustituye localhost:9092 por la lista de nodos separada por comas. Con auto-offset-reset=earliest, un consumidor nuevo lee los mensajes desde el principio cuando todavía no tiene un offset guardado. La propiedad trusted.packages autoriza a JsonDeserializer a reconstruir tus propios tipos a partir de los headers de tipo que escribe el serializador.
El mensaje: un record como DTO
Para que el productor y el consumidor hablen el mismo idioma, define el mensaje como un record de Java. En este caso, un pedido de una tienda online:
public record Pedido(String id, String producto, int cantidad) {
}
El record te da el constructor, los accesores y el equals de forma gratuita. Además, JsonSerializer lo convierte a JSON sin configuración adicional y JsonDeserializer lo reconstruye a partir del header de tipo. Al ser inmutables, los records son una elección segura para el payload de un evento: el objeto que publica el productor es exactamente el mismo que reconstruye el consumidor, sin riesgo de mutaciones intermedias.
Producir mensajes con KafkaTemplate
KafkaTemplate es la clase principal para publicar mensajes. Spring Boot crea el bean automáticamente, así que lo inyectas por constructor como cualquier otra dependencia de tu aplicación:
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
@Service
public class PedidoProducer {
private final KafkaTemplate<String, Pedido> kafkaTemplate;
public PedidoProducer(KafkaTemplate<String, Pedido> kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}
public void enviar(Pedido pedido) {
kafkaTemplate.send("pedidos", pedido.id(), pedido);
}
}
El método send recibe el topic, la clave y el valor. Al usar pedido.id() como clave, todos los eventos de un mismo pedido caen en la misma partición y se procesan en orden. Si no necesitas esa garantía, puedes llamar a send("pedidos", pedido) sin clave.
Consumir mensajes con @KafkaListener
Para leer los mensajes, crea un componente con un método anotado con @KafkaListener. Spring registra el consumidor y lo conecta al topic automáticamente:
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
@Component
public class PedidoConsumer {
@KafkaListener(topics = "pedidos", groupId = "grupo-pedidos")
public void recibir(Pedido pedido) {
System.out.println("Pedido recibido: " + pedido);
}
}
Con esos tres bloques el flujo end-to-end queda completo: PedidoProducer publica el record en el topic pedidos, el broker lo persiste en una partición y PedidoConsumer lo recibe deserializado como objeto. El groupId debe coincidir con el que configuraste en application.properties para que el consumidor participe en el mismo grupo.
¿Quieres probarlo sin instalar nada? La parte de Java puro de este ejemplo, como el record Pedido, puedes ejecutarla en el Java Playground de CodeJa.
Kafka vs RabbitMQ
Si estás decidiendo entre Kafka y RabbitMQ, esta tabla resume las diferencias clave:
| Característica | Kafka | RabbitMQ |
|---|---|---|
| Modelo de mensajería | Publicador-suscriptor | Cola punto a punto |
| Orden de mensajes | Por partición | Por cola (FIFO) |
| Persistencia | En disco, retención configurable | En memoria, opcional en disco |
| Rendimiento | Millones de eventos por segundo | Miles de mensajes por segundo |
| Uso típico | Flujos de eventos y datos | Tareas asíncronas y RPC |
| Casos de uso | Microservicios, logs, analítica | Workflows, notificaciones |
Kafka gana cuando necesitas alto rendimiento, retención de eventos y varios consumidores por mensaje. RabbitMQ es más ligero para encolar tareas puntuales. La elección depende del problema, no de la moda.
Mejores prácticas
- Elige bien el número de particiones. Es la unidad de paralelismo: dos consumidores del mismo grupo nunca leen la misma partición a la vez. Aumentarlas después es complejo.
- Usa la misma clave para preservar el orden. Kafka garantiza el orden dentro de una partición. Si envías los eventos de una misma entidad con la misma clave, siempre caen en la misma partición.
- Define el
group-idde forma explícita. Consumidores con el mismogroup-idreparten las particiones; congroup-iddistintos, cada grupo recibe una copia de cada mensaje. - Serializa con JSON y controla los paquetes de confianza.
JsonSerializerescribe el tipo en un header yJsonDeserializerlo usa para reconstruirlo. En producción limitatrusted.packagesa tus paquetes, no a*. - Haz el consumo idempotente. Por defecto Kafka entrega al menos una vez, así que un mensaje puede llegar duplicado tras un reinicio. Procesa con claves de idempotencia o deduplica antes de escribir.
Si este es tu primer contacto con el ecosistema, la serie de tutoriales de Spring Boot te da el contexto que necesitas para integrar Kafka en un proyecto real.
Preguntas Frecuentes
¿Qué es Kafka y para qué sirve?
Kafka es un sistema de mensajería distribuido que publica y consume flujos de eventos en tiempo real. Sirve para desacoplar productores y consumidores, mover grandes volúmenes de datos y construir arquitecturas basadas en eventos. Es la pieza central de muchos pipelines de datos y sistemas de microservicios.
¿Cómo integro Kafka con Spring Boot?
Añades la dependencia spring-kafka y configuras spring.kafka.bootstrap-servers en application.properties. Spring Boot auto-configura las fábricas de productor y consumidor. Con KafkaTemplate publicas mensajes y con @KafkaListener los consumes.
¿Qué diferencia hay entre un topic y una partición?
Un topic es una categoría donde se publican los mensajes de un mismo tipo. Cada topic se divide en particiones, que son las unidades de orden y paralelismo. Kafka garantiza el orden dentro de cada partición, no entre particiones.
¿Kafka garantiza el orden de los mensajes?
Kafka garantiza el orden dentro de una misma partición. Para que los mensajes de una misma entidad lleguen en orden, envíalos con la misma clave para que caigan en la misma partición. Sin clave, el reparto entre particiones no conserva un orden global.
¿Cuándo debería usar Kafka en vez de RabbitMQ?
Kafka brilla en flujos de eventos con alto rendimiento, retención en disco y múltiples consumidores por mensaje. RabbitMQ es más simple para colas de tareas y mensajería punto a punto. Muchos equipos combinan ambos según el caso de uso.
Artículos Relacionados
Newsletter Semanal de Java
Cada viernes recibe lo más nuevo del ecosistema Java: frameworks, herramientas y mejores prácticas.
🔒 Sin spam. Cancela cuando quieras.