CircuitBreaker 过滤器

Spring Cloud CircuitBreaker GatewayFilter 工厂使用 Spring Cloud CircuitBreaker API 将 Gateway 路由包装在熔断器中。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 表达式 转发原始主机或 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://:9994"))
                .build());
    }
}

在此示例中,网关应用程序中没有 fallback 端点或处理程序。但是,在另一个应用程序中有一个,注册在 localhost:9994 下。

如果请求被转发到回退,Spring Cloud CircuitBreaker Gateway 过滤器还提供导致回退的 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();
    }
}
© . This site is unofficial and not affiliated with VMware.