In a microservices architecture, tracing a single request that flows across multiple services is essential for debugging, monitoring, and performance analysis.
Spring Cloud Sleuth and Zipkin help trace and visualize requests across services.
π What is Distributed Tracing?
Distributed tracing allows you to track a request as it moves through multiple microservices. It helps answer:
- Which services were involved?
- How much time did each take?
- Where are the bottlenecks or failures?
π οΈ Key Tools
Tool | Purpose |
---|---|
Sleuth | Automatically adds trace & span IDs to logs |
Zipkin | Aggregates traces and provides a UI to analyze them |
π§± Architecture
[Client] β [Service A] β [Service B] β [Service C]
\_________ Sleuth sends data to Zipkin _________/
βοΈ Step-by-Step Setup
πΉ 1. Add Dependencies (Each Microservice)
In pom.xml
:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
π Make sure your
spring-cloud.version
matches your Spring Boot version.
πΉ 2. Basic Configuration
In application.yml
:
spring:
application:
name: service-a
zipkin:
base-url: http://localhost:9411
enabled: true
sleuth:
sampler:
probability: 1.0 # 100% of requests will be traced (for development)
πΉ 3. Run Zipkin Server
Option 1: Use Docker
docker run -d -p 9411:9411 openzipkin/zipkin
Zipkin UI: http://localhost:9411
Option 2: Run from JAR
Download the Zipkin JAR from https://zipkin.io and run:
java -jar zipkin-server.jar
π How Sleuth Works (Behind the Scenes)
- Trace ID: A unique identifier for the entire request flow.
- Span ID: Represents a single unit of work (e.g., a method or service call).
- Parent Span ID: Refers to the calling span.
Sleuth injects these into logs and headers automatically:
[TraceId=abc123] [SpanId=def456] Calling Service B
HTTP Headers:
Header | Meaning |
---|---|
X-B3-TraceId | ID of the trace |
X-B3-SpanId | ID of the current span |
X-B3-ParentSpanId | Parent span |
X-B3-Sampled | Whether it should be traced |
π§ͺ Test: Simulate a Multi-Service Call
- Service A calls Service B
- Both log their trace and span info
Controller in Service A
@RestController
@RequestMapping("/a")
public class ServiceAController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/callB")
public String callB() {
return restTemplate.getForObject("http://localhost:8082/b/hello", String.class);
}
}
Controller in Service B
@RestController
@RequestMapping("/b")
public class ServiceBController {
@GetMapping("/hello")
public String sayHello() {
return "Hello from B!";
}
}
Logs in both services will include the same trace ID.
π§ RestTemplate + Sleuth (Auto-propagation)
Sleuth automatically injects tracing headers in RestTemplate
and WebClient
.
Make sure RestTemplate
is a Spring Bean:
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
π View in Zipkin UI
- Visit http://localhost:9411
- Search by service name
- Explore request timelines and call chains
π‘οΈ Best Practices
Tip | Why It Matters |
---|---|
Use lower sample rate in production | Reduce performance overhead |
Always use beans for HTTP clients | Enables auto-injection of trace headers |
Combine with ELK/Grafana | For complete observability stack |
π§° Alternatives
Tool | Description |
---|---|
Jaeger | OpenTracing-compatible distributed tracer |
OpenTelemetry | Modern standard, supports multiple exporters |
π¦ Summary
- Sleuth adds trace IDs to logs and headers.
- Zipkin visualizes traces across services.
- Helps debug, monitor, and optimize microservice chains.
β‘οΈ Next Up: Part 19 β Spring Cloud Config & Centralized Configuration Management