Hoy nos equiparemos con Sleuth y Zipkin para implementar el trazado de peticiones entre varios microservicios. Tendremos dos microservicios simples:
- Servicio A — envía una petición HTTP al Servicio B.
- Servicio B — procesa la petición y responde.
Al final podremos visualizar el trazado de cada petición en la UI de Zipkin. ¡Vamos a empezar!
Conexión de dependencias
Para funcionar necesitaremos:
Spring BootSpring Cloud SleuthSpring Web- Conexión a Zipkin (ya sea localmente o vía Docker).
Configuración de pom.xml para el Servicio A y B
Añadimos las dependencias necesarias en el pom.xml de nuestros proyectos. Empezamos por incluir Sleuth y Spring Web:
<dependencies>
<!-- Spring Web (para manejar peticiones HTTP) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud Sleuth (para el trazado de peticiones) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<!-- Zipkin (para enviar los datos de trazado a Zipkin) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
</dependencies>
Actualiza maven con el comando mvn install, si tu IDE favorito aún no lo ha hecho.
Configuración de Zipkin
Si aún no tienes Zipkin, lo más fácil es desplegarlo con Docker:
docker run -d -p 9411:9411 openzipkin/zipkin
Tras arrancar, Zipkin estará disponible en: http://localhost:9411. Ábrelo en el navegador — más tarde veremos la visualización del trazado.
Creación de microservicios
El Servicio A se encargará de enviar peticiones al Servicio B. Añadiremos un endpoint REST que hace una petición HTTP al otro servicio.
En la carpeta src/main/java creamos la clase del controlador:
@RestController
@RequestMapping("/serviceA")
public class ServiceAController {
private final RestTemplate restTemplate;
public ServiceAController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping("/callB")
public String callServiceB() {
// Envío de una petición GET al Servicio B
String response = restTemplate.getForObject("http://localhost:8081/serviceB/hello", String.class);
return "Respuesta del Servicio B: " + response;
}
}
Fíjate que usamos RestTemplate para enviar la petición. Esa petición será "trazada" por Sleuth automáticamente.
Ahora añadimos un bean RestTemplate para que Spring Boot lo use:
@Configuration
public class ServiceAConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
El Servicio B procesará la petición HTTP del Servicio A y devolverá una respuesta.
En la carpeta src/main/java crea el controlador para el Servicio B:
@RestController
@RequestMapping("/serviceB")
public class ServiceBController {
@GetMapping("/hello")
public String sayHello() {
return "¡Hola desde el Servicio B!";
}
}
Configuración del trazado
Sleuth añade automáticamente las "etiquetas" (traceId, spanId) a los logs y peticiones. Sin embargo, tenemos que configurarlo para enviar los datos a Zipkin.
Añade las siguientes configuraciones en los archivos application.yml para ambos servicios:
spring:
application:
name: service-a # o service-b, lo cambiamos para cada servicio
sleuth:
sampler:
probability: 1.0 # 100% de las peticiones serán trazadas
zipkin:
base-url: http://localhost:9411 # URL de Zipkin
enabled: true
Ten en cuenta que la opción sampler.probability determina qué porcentaje de peticiones se traza. La ponemos a 1.0 para depuración (esto es 100%).
Ejecución y prueba
Paso 1: Arranca ambos servicios
- Arranca el Servicio B (debe escuchar en el puerto
8081). - Arranca el Servicio A (debe escuchar en el puerto
8080).
Paso 2: Prueba el trazado
- Envía una petición al Servicio A desde el navegador o cualquier cliente HTTP (por ejemplo, Postman):
GET http://localhost:8080/serviceA/callB - En respuesta deberías recibir:
Respuesta del Servicio B: ¡Hola desde el Servicio B!
Comprobar el trazado en la UI de Zipkin
Ve a http://localhost:9411 para ver el trazado. Observa cómo la petición viaja desde el Servicio A al Servicio B y de vuelta. En la UI verás:
- Trace ID — identificador único de la petición.
- Span ID — partes individuales del trazado (por ejemplo, peticiones HTTP).
Retroalimentación y detalles a tener en cuenta
- Errores típicos: si el trazado no aparece en Zipkin, revisa la configuración de
base-urly asegúrate de que Zipkin está arrancado. - Problemas con los puertos: asegúrate de que el Servicio A y el Servicio B están ejecutándose en puertos distintos.
- Pérdida del trazado: verifica que
spring.sleuth.sampler.probabilityesté ajustado a1.0para depuración.
Aplicación real del trazado
Estas habilidades se aplican en proyectos reales. Por ejemplo, la compleja y caprichosa arquitectura de microservicios puede empezar a dar problemas si en algún punto se interrumpe una llamada. Con el trazado podrás localizar rápido al "servicio problemático" y arreglar el fallo.
¡Enhorabuena, ahora estás listo para buscar y resolver bugs en sistemas distribuidos!
GO TO FULL VERSION