複雑なマイクロサービスでは、高度なエラー処理は単純な例外ログを超えています。効果的なエラー処理は、信頼性、拡張性、優れたユーザー エクスペリエンスを維持するために非常に重要です。この記事では、分散システムでのエラーの管理、再試行の処理、カスタム エラー応答の作成、デバッグを容易にする方法でのエラーのログ記録の戦略に焦点を当て、Spring Boot マイクロサービスでのエラー処理の高度なテクニックについて説明します。
Spring Boot での基本的なエラー処理アプローチから始めて、ベースラインを設定しましょう。
Spring Boot は、@ControllerAdvice と @ExceptionHandler を備えたグローバル例外ハンドラーを提供します。この設定により、すべてのコントローラーの例外を 1 か所で処理できるようになります。
@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) { ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage()); return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); } @ExceptionHandler(Exception.class) public ResponseEntity<ErrorResponse> handleGeneralException(Exception ex) { ErrorResponse error = new ErrorResponse("INTERNAL_SERVER_ERROR", "An unexpected error occurred."); return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR); } }
ここで、ErrorResponse はカスタム エラー モデルです:
public class ErrorResponse { private String code; private String message; // Constructors, Getters, and Setters }
すべての例外が一貫したエラー応答形式 (ErrorResponse など) を返すようにすることで、クライアントがエラーを正しく解釈できるようになります。
各例外に一意のエラー ID を割り当てると、サービス全体で特定のエラーを追跡するのに役立ちます。デバッグを容易にするために、この ID を例外の詳細と一緒に記録することもできます。
@ExceptionHandler(Exception.class) public ResponseEntity<ErrorResponse> handleGeneralException(Exception ex) { String errorId = UUID.randomUUID().toString(); log.error("Error ID: {}, Message: {}", errorId, ex.getMessage(), ex); ErrorResponse error = new ErrorResponse("INTERNAL_SERVER_ERROR", "An unexpected error occurred. Reference ID: " + errorId); return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR); }
クライアントは、errorId を含むエラー応答を受け取り、詳細なログに直接リンクしてサポートに報告できます。
分散システムでは、一時的な問題 (ネットワーク タイムアウトなど) は再試行で解決できます。サービスメソッドの再試行ロジックには Spring の @Retryable を使用します。
まず、Spring Retry の依存関係を pom.xml に追加します。
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency>
次に、@EnableRetry を使用して Spring Retry を有効にし、再試行が必要なメソッドにアノテーションを付けます。
@EnableRetry @Service public class ExternalService { @Retryable( value = { ResourceAccessException.class }, maxAttempts = 3, backoff = @Backoff(delay = 2000)) public String callExternalService() throws ResourceAccessException { // Code that calls an external service } @Recover public String recover(ResourceAccessException e) { log.error("External service call failed after retries.", e); return "Fallback response due to error."; } }
この設定では、メソッドを最大 3 回再試行し、試行の間に 2 秒の遅延を設けます。すべての試行が失敗した場合、リカバリ メソッドがフォールバックとして実行されます。
サービス間呼び出しでのエラー処理のために、Feign は再試行とフォールバックを設定する宣言的な方法を提供します。
フォールバック サポートを備えた Feign クライアントを定義します:
@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) { ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage()); return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); } @ExceptionHandler(Exception.class) public ResponseEntity<ErrorResponse> handleGeneralException(Exception ex) { ErrorResponse error = new ErrorResponse("INTERNAL_SERVER_ERROR", "An unexpected error occurred."); return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR); } }
このアプローチにより、在庫サービスが利用できない場合に、事前定義された応答で InventoryServiceFallback が開始されます。
ELK (Elasticsearch、Logstash、Kibana) スタックを構成して、複数のマイクロサービスからのログを統合します。集中ログ システムを使用すると、サービス間で問題を簡単に追跡し、関連するエラー ID とともにログを表示できます。
たとえば、application.yml でログ パターンを構成します。
public class ErrorResponse { private String code; private String message; // Constructors, Getters, and Setters }
分散システムでは、複数のサービスにわたる単一のトランザクションを追跡することが重要です。 Spring Cloud Sleuth は、一意のトレース ID とスパン ID を使用した分散トレースを提供します。
依存関係に Spring Cloud Sleuth を追加します:
@ExceptionHandler(Exception.class) public ResponseEntity<ErrorResponse> handleGeneralException(Exception ex) { String errorId = UUID.randomUUID().toString(); log.error("Error ID: {}, Message: {}", errorId, ex.getMessage(), ex); ErrorResponse error = new ErrorResponse("INTERNAL_SERVER_ERROR", "An unexpected error occurred. Reference ID: " + errorId); return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR); }
カスタム例外を定義して、より具体的なエラー処理を提供します。
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency>
構造化され強化されたエラー メッセージの ErrorAttributes を実装して、エラー応答をカスタマイズします。
@EnableRetry @Service public class ExternalService { @Retryable( value = { ResourceAccessException.class }, maxAttempts = 3, backoff = @Backoff(delay = 2000)) public String callExternalService() throws ResourceAccessException { // Code that calls an external service } @Recover public String recover(ResourceAccessException e) { log.error("External service call failed after retries.", e); return "Fallback response due to error."; } }
構成に CustomErrorAttributes を登録して、すべてのエラー応答を自動的にカスタマイズします。
標準化された API エラー構造には問題の詳細形式を使用します。 RFC 7807 に基づいてエラー応答モデルを定義します:
@FeignClient(name = "inventory-service", fallback = InventoryServiceFallback.class) public interface InventoryServiceClient { @GetMapping("/api/inventory/{id}") InventoryResponse getInventory(@PathVariable("id") Long id); } @Component public class InventoryServiceFallback implements InventoryServiceClient { @Override public InventoryResponse getInventory(Long id) { // Fallback logic, like returning cached data or an error response return new InventoryResponse(id, "N/A", "Fallback inventory"); } }
次に、@ControllerAdvice メソッドからこの構造化された応答を返し、すべての API で一貫したエラー構造を維持します。
logging: pattern: console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
サーキット ブレーカー パターンを統合すると、マイクロサービスが失敗したサービスを繰り返し呼び出すことから保護されます。
Resilience4j サーキットブレーカーの使用
Resilience4j を依存関係に追加します:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency>
次に、メソッドをサーキット ブレーカーでラップします。
public class InvalidRequestException extends RuntimeException { public InvalidRequestException(String message) { super(message); } }
このセットアップは、複数回失敗すると getInventory の呼び出しを停止し、代わりに inventoryFallback が安全な応答を返します。
Spring Boot マイクロサービスの高度なエラー処理には次のものが含まれます。
集中エラー処理により、一貫した応答と簡素化されたデバッグが実現します。
再試行とサーキット ブレーカーにより、回復力のあるサービス間呼び出しを実現します。
ELK や Sleuth などのツールによる一元的なログ記録とトレーサビリティ。
カスタム エラー形式。問題の詳細と構造化されたエラー応答が含まれます。
これらの手法は、マイクロサービスの堅牢性を確保し、一貫した追跡可能なエラー応答を提供しながら、サービス間でのカスケード障害を防止するのに役立ちます。
以上がSpring Boot マイクロサービスの高度なエラー処理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。