Skip to content

Commit 9c43d85

Browse files
authored
feat: Distributed tracing (iluwatar#3006)
* added microservices distributed tracing pattern * feat: Implement Microservice pattern: Distributed tracing iluwatar#2693
1 parent 1d454f7 commit 9c43d85

35 files changed

+1724
-0
lines changed

Diff for: microservices-distributed-tracing/README.md

+201
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
---
2+
title: "Microservices Distributed Tracing Pattern: Enhancing Visibility in Service Communication"
3+
shortTitle: Distributed Tracing in Microservices
4+
description: "Learn how the Distributed Tracing pattern enhances visibility into service communication across microservices. Discover its benefits, implementation examples, and best practices."
5+
category: Integration
6+
language: en
7+
tag:
8+
- Distributed tracing
9+
- Microservices architecture
10+
- Service communication
11+
- Performance monitoring
12+
- Scalability
13+
- Observability
14+
---
15+
16+
## Intent of Microservices Distributed Tracing Design Pattern
17+
18+
Distributed tracing aims to monitor and track requests as they flow through different services in a microservices architecture, providing insights into performance, dependencies, and failures.
19+
20+
## Also known as
21+
22+
* Distributed Request Tracing
23+
* End-to-End Tracing
24+
25+
## Detailed Explanation of Microservices Distributed Tracing Pattern with Real-World Examples
26+
27+
Real-world example
28+
29+
> In an e-commerce platform, distributed tracing is used to track a customer's request from the moment they add an item to the cart until the order is processed and shipped. This helps in identifying bottlenecks, errors, and latency issues across different services.
30+
31+
In plain words
32+
33+
> Distributed tracing allows you to follow a request's journey through all the services it interacts with, providing insights into system performance and aiding in debugging.
34+
35+
Wikipedia says
36+
37+
> Tracing in software engineering refers to the process of capturing and recording information about the execution of a software program. This information is typically used by programmers for debugging purposes, and additionally, depending on the type and detail of information contained in a trace log, by experienced system administrators or technical-support personnel and by software monitoring tools to diagnose common problems with software.
38+
39+
## Programmatic Example of Microservices Distributed Tracing in Java
40+
41+
42+
This implementation shows how an e-commerce platform's `OrderService` interacts with both `PaymentService` and `ProductService`. When a customer places an order, the `OrderService` calls the `PaymentService` to process the payment and the `ProductService` to check the product inventory. Distributed tracing logs are generated for each of these interactions and can be viewed in the Zipkin interface to monitor the flow and performance of requests across these services.
43+
44+
Here's the `Order microservice` implementation.
45+
46+
```java
47+
@Slf4j
48+
@RestController
49+
public class OrderController {
50+
51+
private final OrderService orderService;
52+
53+
public OrderController(final OrderService orderService) {
54+
this.orderService = orderService;
55+
}
56+
57+
@PostMapping("/order")
58+
public ResponseEntity<String> processOrder(@RequestBody(required = false) String request) {
59+
LOGGER.info("Received order request: {}", request);
60+
var result = orderService.processOrder();
61+
LOGGER.info("Order processed result: {}", result);
62+
return ResponseEntity.ok(result);
63+
}
64+
}
65+
```
66+
```java
67+
@Slf4j
68+
@Service
69+
public class OrderService {
70+
71+
private final RestTemplateBuilder restTemplateBuilder;
72+
73+
public OrderService(final RestTemplateBuilder restTemplateBuilder) {
74+
this.restTemplateBuilder = restTemplateBuilder;
75+
}
76+
77+
public String processOrder() {
78+
if (validateProduct() && processPayment()) {
79+
return "Order processed successfully";
80+
}
81+
return "Order processing failed";
82+
}
83+
84+
Boolean validateProduct() {
85+
try {
86+
ResponseEntity<Boolean> productValidationResult = restTemplateBuilder
87+
.build()
88+
.postForEntity("http://localhost:30302/product/validate", "validating product",
89+
Boolean.class);
90+
LOGGER.info("Product validation result: {}", productValidationResult.getBody());
91+
return productValidationResult.getBody();
92+
} catch (ResourceAccessException | HttpClientErrorException e) {
93+
LOGGER.error("Error communicating with product service: {}", e.getMessage());
94+
return false;
95+
}
96+
}
97+
98+
Boolean processPayment() {
99+
try {
100+
ResponseEntity<Boolean> paymentProcessResult = restTemplateBuilder
101+
.build()
102+
.postForEntity("http://localhost:30301/payment/process", "processing payment",
103+
Boolean.class);
104+
LOGGER.info("Payment processing result: {}", paymentProcessResult.getBody());
105+
return paymentProcessResult.getBody();
106+
} catch (ResourceAccessException | HttpClientErrorException e) {
107+
LOGGER.error("Error communicating with payment service: {}", e.getMessage());
108+
return false;
109+
}
110+
}
111+
}
112+
```
113+
114+
Here's the `Payment microservice` implementation.
115+
116+
```java
117+
118+
@Slf4j
119+
@RestController
120+
public class PaymentController {
121+
122+
@PostMapping("/payment/process")
123+
public ResponseEntity<Boolean> payment(@RequestBody(required = false) String request) {
124+
LOGGER.info("Received payment request: {}", request);
125+
boolean result = true;
126+
LOGGER.info("Payment result: {}", result);
127+
return ResponseEntity.ok(result);
128+
}
129+
}
130+
```
131+
132+
Here's the `Product microservice` implementation.
133+
134+
```java
135+
/**
136+
* Controller for handling product validation requests.
137+
*/
138+
@Slf4j
139+
@RestController
140+
public class ProductController {
141+
142+
/**
143+
* Validates the product based on the request.
144+
*
145+
* @param request the request body containing product information (can be null)
146+
* @return ResponseEntity containing the validation result (true)
147+
*/
148+
@PostMapping("/product/validate")
149+
public ResponseEntity<Boolean> validateProduct(@RequestBody(required = false) String request) {
150+
LOGGER.info("Received product validation request: {}", request);
151+
boolean result = true;
152+
LOGGER.info("Product validation result: {}", result);
153+
return ResponseEntity.ok(result);
154+
}
155+
}
156+
```
157+
158+
## When to Use the Microservices Distributed Tracing Pattern in Java
159+
160+
* When you have a microservices architecture and need to monitor the flow of requests across multiple services.
161+
* When troubleshooting performance issues or errors in a distributed system.
162+
* When you need to gain insights into system bottlenecks and optimize overall performance.
163+
164+
165+
## Microservices Distributed Tracing Pattern Java Tutorials
166+
167+
* [Spring Boot - Tracing (Spring)](https://docs.spring.io/spring-boot/reference/actuator/tracing.html)
168+
* [Reactive Observability (Spring Academy)](https://spring.academy/guides/microservices-observability-reactive-spring-boot-3)
169+
* [Spring Cloud – Tracing Services with Zipkin (Baeldung)](https://dzone.com/articles/getting-started-with-spring-cloud-gateway)
170+
171+
## Benefits and Trade-offs of Microservices Distributed Tracing Pattern
172+
173+
Benefits:
174+
175+
* Provides end-to-end visibility into requests.
176+
* Helps in identifying performance bottlenecks.
177+
* Aids in debugging and troubleshooting complex systems.
178+
179+
Trade-offs:
180+
181+
* Adds overhead to each request due to tracing data.
182+
* Requires additional infrastructure (e.g., Zipkin, Jaeger) for collecting and visualizing traces.
183+
* Can become complex to manage in large-scale systems.
184+
185+
## Real-World Applications of Microservices Distributed Tracing Pattern in Java
186+
187+
* Monitoring and troubleshooting e-commerce platforms.
188+
* Performance monitoring in financial transaction systems.
189+
* Observability in large-scale SaaS applications.
190+
191+
## Related Java Design Patterns
192+
193+
* [Log Aggregation Microservice](https://java-design-patterns.com/patterns/microservices-log-aggregation/) - Distributed tracing works well in conjunction with log aggregation to provide comprehensive observability and troubleshooting capabilities.
194+
* [Circuit Breaker](https://java-design-patterns.com/patterns/circuit-breaker/) - Distributed tracing can be used alongside the Circuit Breaker pattern to monitor and handle failures gracefully, preventing cascading failures in microservices.
195+
* [API Gateway Microservice](https://java-design-patterns.com/patterns/microservices-api-gateway/) - The API Gateway pattern can be integrated with distributed tracing to provide a single entry point for tracing requests across multiple microservices.
196+
197+
## References and Credits
198+
199+
* [Building Microservices](https://amzn.to/3UACtrU)
200+
* [OpenTelemetry Documentation](https://opentelemetry.io/docs/)
201+
* [Distributed tracing (microservices.io)](https://microservices.io/patterns/observability/distributed-tracing.html)
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
@startuml
2+
!theme vibrant
3+
package com.iluwatar.microservices-distributed-tracing {
4+
package "Order Microservice" {
5+
class OrderController {
6+
+processOrder()
7+
}
8+
9+
class OrderService {
10+
+validateProduct()
11+
+processPayment()
12+
}
13+
}
14+
15+
package "Payment Microservice" {
16+
class PaymentController {
17+
+processPayment()
18+
}
19+
}
20+
21+
package "Product Microservice" {
22+
class ProductController {
23+
+validateProduct()
24+
}
25+
}
26+
27+
OrderController --> OrderService
28+
OrderService --> PaymentController : processPayment()
29+
OrderService --> ProductController : validateProduct()
30+
}
31+
@enduml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
@startuml
2+
!theme vibrant
3+
package com.iluwatar.microservices-distributed-tracing {
4+
package "Order Microservice" {
5+
class OrderController {
6+
+processOrder()
7+
}
8+
9+
class OrderService {
10+
+validateProduct()
11+
+processPayment()
12+
}
13+
}
14+
15+
package "Payment Microservice" {
16+
class PaymentController {
17+
+processPayment()
18+
}
19+
}
20+
21+
package "Product Microservice" {
22+
class ProductController {
23+
+validateProduct()
24+
}
25+
}
26+
27+
OrderController --> OrderService
28+
OrderService --> PaymentController : processPayment()
29+
OrderService --> ProductController : validateProduct()
30+
}
31+
@enduml
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@startuml
2+
!theme vibrant
3+
package com.iluwatar.microservices-distributed-tracing {
4+
package "Order Microservice" {
5+
class OrderController {
6+
+processOrder()
7+
}
8+
9+
class OrderService {
10+
+validateProduct()
11+
+processPayment()
12+
}
13+
}
14+
}
15+
@enduml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@startuml
2+
!theme vibrant
3+
package com.iluwatar.microservices-distributed-tracing {
4+
package "Order Microservice" {
5+
class OrderController {
6+
+processOrder()
7+
}
8+
9+
class OrderService {
10+
+validateProduct()
11+
+processPayment()
12+
}
13+
}
14+
}
15+
@enduml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
5+
6+
The MIT License
7+
Copyright © 2014-2022 Ilkka Seppälä
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in
17+
all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
27+
-->
28+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
29+
<parent>
30+
<artifactId>microservices-distributed-tracing</artifactId>
31+
<groupId>com.iluwatar</groupId>
32+
<version>1.26.0-SNAPSHOT</version>
33+
</parent>
34+
<modelVersion>4.0.0</modelVersion>
35+
<artifactId>order-microservice</artifactId>
36+
<packaging>jar</packaging>
37+
<build>
38+
<plugins>
39+
<plugin>
40+
<groupId>org.apache.maven.plugins</groupId>
41+
<artifactId>maven-assembly-plugin</artifactId>
42+
<executions>
43+
<execution>
44+
<configuration>
45+
<archive>
46+
<manifest>
47+
<mainClass>com.iluwatar.order.microservice.com.iluwatar.product.microservice.Main</mainClass>
48+
</manifest>
49+
</archive>
50+
</configuration>
51+
</execution>
52+
</executions>
53+
</plugin>
54+
</plugins>
55+
</build>
56+
<repositories>
57+
<repository>
58+
<id>central</id>
59+
<name>Maven Central Repository</name>
60+
<url>https://repo.maven.apache.org/maven2</url>
61+
</repository>
62+
</repositories>
63+
</project>

0 commit comments

Comments
 (0)