最新の安定バージョンについては、Spring Cloud Gateway 5.0.1 を使用してください!

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();
}