Lab 13: Use Zipkin to Collect, Analyze, and Visualize Traces in Your Microservices Architecture (Spring Boot 3.4.1)
Learn how to integrate Spring Cloud Sleuth with Zipkin to collect and visualize distributed traces in a Spring Boot 3.4.1 microservices architecture. You will configure two services (UserService
and OrderService
) to send trace data to a local Zipkin server and analyze end-to-end request flows via the Zipkin dashboard.
-
Ensure Java is installed (for running Zipkin).
- Check Java:
java -version
- If not installed, install JDK 17 (e.g., from AdoptOpenJDK).
- Check Java:
-
Download the Zipkin Server.
- Visit Zipkin Quickstart and download the latest Zipkin JAR file (e.g.,
zipkin-server-2.x.x-exec.jar
). - Save it in a folder like
~/zipkin
orC:\Zipkin
.
- Visit Zipkin Quickstart and download the latest Zipkin JAR file (e.g.,
-
Run the Zipkin server locally.
- From the directory with the Zipkin JAR:
java -jar zipkin-server-2.x.x-exec.jar
- Zipkin listens on port 9411 by default.
- From the directory with the Zipkin JAR:
-
Verify Zipkin is running.
- Open:
http://localhost:9411
- The Zipkin dashboard should appear.
- Open:
-
Generate a new Spring Boot project for
UserService
.- Spring Boot Version: 3.4.1
- Group Id:
com.microservices
- Artifact Id:
user-service
- Name:
UserService
- Dependencies:
- Spring Web
- Spring Boot Actuator
- Spring Cloud Sleuth
- Extract into a folder named
UserService
.
-
Import
UserService
into your IDE. -
Configure
UserService
to send traces to Zipkin.- In
src/main/resources/application.properties
:server.port=8081 spring.application.name=user-service spring.zipkin.base-url=http://localhost:9411 spring.sleuth.sampler.probability=1.0
sampler.probability=1.0
means all requests are traced.
- In
-
Create a REST controller in
UserService
.UserController.java
:package com.microservices.userservice; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @GetMapping("/users") public String getUsers() { return "List of users from UserService"; } }
-
Run
UserService
.- From the
UserService
directory:./mvnw spring-boot:run
- It listens on 8081.
- From the
-
Test the
/users
endpoint.- Access:
http://localhost:8081/users
- Confirm it returns
"List of users from UserService"
.
- Access:
-
Generate a new Spring Boot project for
OrderService
.- Artifact Id:
order-service
- Dependencies:
- Spring Web
- Spring Boot Actuator
- Spring Cloud Sleuth
- Spring WebClient
- Extract into a folder named
OrderService
.
- Artifact Id:
-
Import
OrderService
into your IDE. -
Configure
OrderService
to send traces to Zipkin.- In
src/main/resources/application.properties
:server.port=8082 spring.application.name=order-service spring.zipkin.base-url=http://localhost:9411 spring.sleuth.sampler.probability=1.0
- In
-
Create a REST controller in
OrderService
.OrderController.java
:package com.microservices.orderservice; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.reactive.function.client.WebClient; @RestController public class OrderController { @Autowired private WebClient.Builder webClientBuilder; @GetMapping("/orders") public String getOrders() { String users = webClientBuilder.build() .get() .uri("http://localhost:8081/users") .retrieve() .bodyToMono(String.class) .block(); return "Orders from OrderService and Users: " + users; } }
-
Add WebClient configuration.
- In
OrderServiceApplication.java
:package com.microservices.orderservice; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.web.reactive.function.client.WebClient; @SpringBootApplication public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } @Bean public WebClient.Builder webClientBuilder() { return WebClient.builder(); } }
- In
-
Run
OrderService
.- From
OrderService
:./mvnw spring-boot:run
- It listens on 8082.
- From
-
Test the
/orders
endpoint.- Access:
http://localhost:8082/orders
- It retrieves data from
UserService
on8081
.
- Access:
-
Generate traffic between the services.
- Hit
http://localhost:8082/orders
multiple times.
- Hit
-
Access the Zipkin dashboard.
- Go to:
http://localhost:9411
- You should see the Zipkin UI.
- Go to:
-
Search for traces.
- Click Find Traces on the Zipkin dashboard.
- Look for spans involving
order-service
anduser-service
.
-
Analyze a specific trace.
- Click a trace to see details, including:
- Spans (segments of the request)
- Timing (latency)
- Service dependencies.
- Click a trace to see details, including:
-
Add a third microservice.
- E.g.,
ProductService
callsUserService
. See how Zipkin links all three in a single trace.
- E.g.,
-
Simulate service failure or slowdown.
- Make
UserService
throw an exception or introduce a delay and observe the trace in Zipkin.
- Make
-
Experiment with sampling rates.
- Adjust
spring.sleuth.sampler.probability
to reduce overhead in production scenarios.
- Adjust
By finishing this lab, you have:
- Installed and ran Zipkin locally on port 9411.
- Configured two microservices (
UserService
,OrderService
) with Spring Cloud Sleuth to send trace data to Zipkin. - Observed trace data (service calls, latencies, errors) in the Zipkin dashboard.
- Validated how distributed tracing simplifies root cause analysis and performance tuning across microservices.