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

CircuitBreaker フィルター

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 フィルターを構成します。

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: circuitbreakernofallback
          uri: https://example.org
          predicates:
          - Path=/anything/circuitbreakernofallback
          filters:
          - CircuitBreaker=myCircuitBreaker
GatewaySampleApplication.java
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
import static org.springframework.cloud.gateway.server.mvc.filter.CircuitBreakerFilterFunctions.circuitBreaker;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;

@Configuration
class RouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> gatewayRouterFunctionsCircuitBreakerNoFallback() {
        return route("circuitbreakernofallback")
            .route(path("/anything/circuitbreakernofallback"), http())
            .before(uri("https://example.org"))
            .filter(circuitBreaker("myCircuitBreaker"))
            .build();
    }
}

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

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

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: circuitbreaker_route
          uri: https://example.org
          predicates:
          - Path=/consumingServiceEndpoint
          filters:
          - name: CircuitBreaker
            args:
              name: myCircuitBreaker
              fallbackUri: forward:/inCaseOfFailureUseThis

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

GatewaySampleApplication.java
import java.net.URI;
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
import static org.springframework.cloud.gateway.server.mvc.filter.CircuitBreakerFilterFunctions.circuitBreaker;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;

@Configuration
class RouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> gatewayRouterFunctionsCircuitBreakerFallback() {
        return route("circuitbreaker_route")
            .route(path("/consumingServiceEndpoint"), http())
            .before(uri("https://example.org"))
            .filter(circuitBreaker("myCircuitBreaker", URI.create("forward:/inCaseOfFailureUseThis")))
            .build();
    }
}

この例では、サーキットブレーカーのフォールバックが呼び出されたときに、/inCaseofFailureUseThis URI に転送します。

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

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

GatewaySampleApplication.java
import java.net.URI;
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
import static org.springframework.cloud.gateway.server.mvc.filter.CircuitBreakerFilterFunctions.circuitBreaker;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;

@Configuration
class RouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> gatewayRouterFunctionsCircuitBreakerFallback() {
        return route("circuitbreaker_route")
            .route(path("/consumingServiceEndpoint/{*segments}"), http())
            .before(uri("https://example.org"))
            .filter(circuitBreaker("myCircuitBreaker", URI.create("forward:/inCaseOfFailureUseThis/{segments}")))
            .build();
    }
}

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

GatewaySampleApplication.java
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
import static org.springframework.cloud.gateway.server.mvc.filter.CircuitBreakerFilterFunctions.circuitBreaker;
import static org.springframework.cloud.gateway.server.mvc.filter.LoadBalancerFilterFunctions.lb;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;

@Configuration
class RouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> gatewayRouterFunctionsCircuitBreakerFallbackToGatewayRoute() {
        return route("ingredients")
                .route(path("/ingredients/**"), http())
                .filter(lb("ingredients"))
                .filter(circuitBreaker("fetchIngredients", URI.create("forward:/fallback")))
                .build()
            .and(route("ingredients-fallback")
                .route(path("/fallback"), http())
                .before(uri("https://localhost:9994"))
                .build());
    }
}

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

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

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

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

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

application.yml
spring:
  cloud:
    gateway:
      mvc:
        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"
GatewaySampleApplication.java
import java.net.URI;
import static org.springframework.cloud.gateway.server.mvc.filter.CircuitBreakerFilterFunctions.circuitBreaker;
import static org.springframework.cloud.gateway.server.mvc.filter.LoadBalancerFilterFunctions.lb;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;

@Configuration
class RouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> gatewayRouterFunctionsCircuitBreakerFallback() {
        return route("circuitbreaker_route")
                .route(path("/consumingServiceEndpoint"), http())
                .filter(lb("backing-service"))
				.filter(circuitBreaker(config -> config.setId("myCircuitBreaker").setFallbackUri("forward:/inCaseOfFailureUseThis").setStatusCodes("500", "NOT_FOUND")))
                .build();
    }
}