CircuitBreaker GatewayFilter ファクトリ

Spring Cloud CircuitBreaker GatewayFilter ファクトリは、Spring Cloud CircuitBreaker API を使用して、ゲートウェイルートをサーキットブレーカーにラップします。Spring Cloud CircuitBreaker は、Spring Cloud Gateway で使用できる複数のライブラリをサポートします。Spring Cloud は、そのまま Resilience4J をサポートします。

Spring Cloud CircuitBreaker フィルターを有効にするには、クラスパスに spring-cloud-starter-circuitbreaker-reactor-resilience4j を配置する必要があります。次の例では、Spring Cloud CircuitBreaker GatewayFilter を構成します。

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: https://example.org
        filters:
        - CircuitBreaker=myCircuitBreaker

サーキットブレーカーを構成するには、使用している基礎となるサーキットブレーカーの実装の構成を参照してください。

Spring Cloud CircuitBreaker フィルターは、オプションの fallbackUri パラメーターを受け入れることもできます。現在、forward: スキーム化 URI のみがサポートされています。フォールバックが呼び出されると、リクエストは URI と一致するコントローラーに転送されます。次の例では、このようなフォールバックを構成します。

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: lb://backing-service:8088
        predicates:
        - Path=/consumingServiceEndpoint
        filters:
        - name: CircuitBreaker
          args:
            name: myCircuitBreaker
            fallbackUri: forward:/inCaseOfFailureUseThis
        - RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint

次のリストは、Java でも同じことを行います。

Application.java
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
            .filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis"))
                .rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
        .build();
}

この例では、サーキットブレーカーのフォールバックが呼び出されたときに /inCaseofFailureUseThis URI に転送します。この例は、(オプションの)Spring Cloud LoadBalancer ロードバランシング(宛先 URI の lb プレフィックスによって定義される)も示していることに注意してください。

CircuitBreaker は fallbackUri の URI 変数もサポートします。これにより、元のホストの転送セクションや PathPattern 式 (Javadoc) を使用した URL パスなど、より複雑なルーティングオプションが可能になります。

以下の例では、呼び出し consumingServiceEndpoint/users/1 が inCaseOfFailureUseThis/users/1 にリダイレクトされます。

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: lb://backing-service:8088
        predicates:
        - Path=/consumingServiceEndpoint/{*segments}
        filters:
        - name: CircuitBreaker
          args:
            name: myCircuitBreaker
            fallbackUri: forward:/inCaseOfFailureUseThis/{segments}

主なシナリオは、fallbackUri を使用して、ゲートウェイアプリケーション内の内部コントローラーまたはハンドラーを定義することです。ただし、次のように、リクエストを外部アプリケーションのコントローラーまたはハンドラーに再ルーティングすることもできます。

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: ingredients
        uri: lb://ingredients
        predicates:
        - Path=//ingredients/**
        filters:
        - name: CircuitBreaker
          args:
            name: fetchIngredients
            fallbackUri: forward:/fallback
      - id: ingredients-fallback
        uri: http://localhost:9994
        predicates:
        - Path=/fallback

この例では、ゲートウェイアプリケーションに fallback エンドポイントまたはハンドラーはありません。ただし、localhost:9994 で登録されている別のアプリケーションに 1 つあります。

リクエストがフォールバックに転送される場合、Spring Cloud CircuitBreaker ゲートウェイフィルターは、それを引き起こした Throwable も提供します。これは、ゲートウェイアプリケーション内でフォールバックを処理するときに使用できる ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR 属性として ServerWebExchange に追加されます。

外部コントローラー / ハンドラーのシナリオでは、例外の詳細とともにヘッダーを追加できます。これを行う方法の詳細については、FallbackHeaders GatewayFilter ファクトリセクションを参照してください。

ステータスコードでサーキットブレーカーをトリップする

場合によっては、ラップするルートから返されたステータスコードに基づいてサーキットブレーカーを作動させたい場合があります。サーキットブレーカーの構成オブジェクトは、返された場合にサーキットブレーカーが作動する状態コードのリストを取得します。サーキットブレーカーを作動させたいステータスコードを設定するときは、ステータスコード値で整数を使用するか、HttpStatus 列挙型の文字列表現を使用できます。

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: lb://backing-service:8088
        predicates:
        - Path=/consumingServiceEndpoint
        filters:
        - name: CircuitBreaker
          args:
            name: myCircuitBreaker
            fallbackUri: forward:/inCaseOfFailureUseThis
            statusCodes:
              - 500
              - "NOT_FOUND"
Application.java
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
            .filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis").addStatusCode("INTERNAL_SERVER_ERROR"))
                .rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
        .build();
}