マイクロサービス分散トレーシングパターン:サービス通信における可視性の向上
マイクロサービス分散トレーシングデザインパターンの意図
分散トレーシングは、マイクロサービスアーキテクチャにおける異なるサービスを通過するリクエストを監視および追跡することを目的としており、パフォーマンス、依存関係、および障害に関する洞察を提供します。
別名
- 分散リクエストトレーシング
- エンドツーエンドトレーシング
マイクロサービス分散トレーシングパターンの詳細な説明と実世界の例
現実世界の例
eコマースプラットフォームでは、顧客が商品をカートに追加した瞬間から注文が処理され、出荷されるまでの顧客のリクエストを追跡するために分散トレーシングが使用されます。これは、さまざまなサービスにおけるボトルネック、エラー、およびレイテンシの問題を特定するのに役立ちます。
平易な言葉で言うと
分散トレーシングを使用すると、リクエストがやり取りするすべてのサービスを通過する旅を追跡でき、システムパフォーマンスに関する洞察を提供し、デバッグに役立ちます。
Wikipediaによると
ソフトウェアエンジニアリングにおけるトレーシングとは、ソフトウェアプログラムの実行に関する情報をキャプチャして記録するプロセスを指します。この情報は通常、プログラマーがデバッグ目的で使用し、さらに、トレースログに含まれる情報の種類と詳細に応じて、経験豊富なシステム管理者または技術サポート担当者、およびソフトウェア監視ツールがソフトウェアの一般的な問題を診断するために使用します。
Javaにおけるマイクロサービス分散トレーシングのプログラム例
この実装は、eコマースプラットフォームのOrderService
がPaymentService
とProductService
の両方とどのようにやり取りするかを示しています。顧客が注文をすると、OrderService
はPaymentService
を呼び出して支払いを処理し、ProductService
を呼び出して製品在庫を確認します。これらのやり取りごとに分散トレーシングログが生成され、これらのサービス全体のリクエストの流れとパフォーマンスを監視するためにZipkinインターフェースで表示できます。
これがOrderマイクロサービス
の実装です。
@Slf4j
@RestController
public class OrderController {
private final OrderService orderService;
public OrderController(final OrderService orderService) {
this.orderService = orderService;
}
@PostMapping("/order")
public ResponseEntity<String> processOrder(@RequestBody(required = false) String request) {
LOGGER.info("Received order request: {}", request);
var result = orderService.processOrder();
LOGGER.info("Order processed result: {}", result);
return ResponseEntity.ok(result);
}
}
@Slf4j
@Service
public class OrderService {
private final RestTemplateBuilder restTemplateBuilder;
public OrderService(final RestTemplateBuilder restTemplateBuilder) {
this.restTemplateBuilder = restTemplateBuilder;
}
public String processOrder() {
if (validateProduct() && processPayment()) {
return "Order processed successfully";
}
return "Order processing failed";
}
Boolean validateProduct() {
try {
ResponseEntity<Boolean> productValidationResult = restTemplateBuilder
.build()
.postForEntity("http://localhost:30302/product/validate", "validating product",
Boolean.class);
LOGGER.info("Product validation result: {}", productValidationResult.getBody());
return productValidationResult.getBody();
} catch (ResourceAccessException | HttpClientErrorException e) {
LOGGER.error("Error communicating with product service: {}", e.getMessage());
return false;
}
}
Boolean processPayment() {
try {
ResponseEntity<Boolean> paymentProcessResult = restTemplateBuilder
.build()
.postForEntity("http://localhost:30301/payment/process", "processing payment",
Boolean.class);
LOGGER.info("Payment processing result: {}", paymentProcessResult.getBody());
return paymentProcessResult.getBody();
} catch (ResourceAccessException | HttpClientErrorException e) {
LOGGER.error("Error communicating with payment service: {}", e.getMessage());
return false;
}
}
}
これがPaymentマイクロサービス
の実装です。
@Slf4j
@RestController
public class PaymentController {
@PostMapping("/payment/process")
public ResponseEntity<Boolean> payment(@RequestBody(required = false) String request) {
LOGGER.info("Received payment request: {}", request);
boolean result = true;
LOGGER.info("Payment result: {}", result);
return ResponseEntity.ok(result);
}
}
これがProductマイクロサービス
の実装です。
/**
* Controller for handling product validation requests.
*/
@Slf4j
@RestController
public class ProductController {
/**
* Validates the product based on the request.
*
* @param request the request body containing product information (can be null)
* @return ResponseEntity containing the validation result (true)
*/
@PostMapping("/product/validate")
public ResponseEntity<Boolean> validateProduct(@RequestBody(required = false) String request) {
LOGGER.info("Received product validation request: {}", request);
boolean result = true;
LOGGER.info("Product validation result: {}", result);
return ResponseEntity.ok(result);
}
}
Javaでマイクロサービス分散トレーシングパターンを使用する場合
- マイクロサービスアーキテクチャがあり、複数のサービスを通過するリクエストの流れを監視する必要がある場合。
- 分散システムでパフォーマンスの問題やエラーのトラブルシューティングを行う場合。
- システムのボトルネックに関する洞察を得て、全体的なパフォーマンスを最適化する必要がある場合。
マイクロサービス分散トレーシングパターンJavaチュートリアル
- Spring Boot - トレーシング (Spring)
- リアクティブ可観測性 (Spring Academy)
- Spring Cloud – Zipkinを使用したサービスのトレーシング (Baeldung)
マイクロサービス分散トレーシングパターンの利点とトレードオフ
利点
- リクエストへのエンドツーエンドの可視性を提供します。
- パフォーマンスのボトルネックの特定に役立ちます。
- 複雑なシステムのデバッグとトラブルシューティングに役立ちます。
トレードオフ
- トレーシングデータにより、各リクエストにオーバーヘッドが追加されます。
- トレースを収集および視覚化するための追加インフラストラクチャ (例: Zipkin、Jaeger) が必要です。
- 大規模システムでは管理が複雑になる可能性があります。
Javaにおけるマイクロサービス分散トレーシングパターンの実世界での応用
- eコマースプラットフォームの監視とトラブルシューティング。
- 金融取引システムにおけるパフォーマンス監視。
- 大規模SaaSアプリケーションにおける可観測性。
関連するJavaデザインパターン
- ログ集約マイクロサービス - 分散トレーシングは、包括的な可観測性とトラブルシューティング機能を提供するために、ログ集約と連携してうまく機能します。
- サーキットブレーカー - 分散トレーシングは、サーキットブレーカーパターンと並行して使用して、障害を監視および適切に処理し、マイクロサービスでのカスケード障害を防ぐことができます。
- APIゲートウェイマイクロサービス - APIゲートウェイパターンは、分散トレーシングと統合して、複数のマイクロサービスにわたるリクエストをトレースするための単一のエントリポイントを提供できます。