CircuitBreaker GatewayFilter 工厂
Spring Cloud 断路器网关过滤器工厂使用 Spring Cloud 断路器 API 将网关路由包装在断路器中。Spring Cloud 断路器支持多个库,这些库可以与 Spring Cloud Gateway 一起使用。Spring Cloud 开箱即用地支持 Resilience4J。
要启用 Spring Cloud 断路器过滤器,您需要将 spring-cloud-starter-circuitbreaker-reactor-resilience4j 放在类路径上。以下示例配置了一个 Spring Cloud 断路器 GatewayFilter
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: https://example.org
filters:
- CircuitBreaker=myCircuitBreaker
要配置断路器,请参阅您正在使用的底层断路器实现的配置。
Spring Cloud 断路器过滤器还可以接受一个可选的 fallbackUri 参数。目前,只支持 forward: 方案的 URI。如果调用了回退,请求将转发到与 URI 匹配的控制器。以下示例配置了这样的回退
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 中执行相同的操作
@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 前缀定义)。
断路器还支持 fallbackUri 中的 URI 变量。这允许更复杂的路由选项,例如使用 PathPattern 表达式转发原始主机或 URL 路径的某些部分。
在下面的示例中,对 consumingServiceEndpoint/users/1 的调用将被重定向到 inCaseOfFailureUseThis/users/1。
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 在网关应用程序中定义内部控制器或处理器。但是,您也可以将请求重新路由到外部应用程序中的控制器或处理器,如下所示
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: https://:9994
predicates:
- Path=/fallback
在此示例中,网关应用程序中没有 fallback 端点或处理器。但是,在另一个应用程序中有一个,注册在 localhost:9994 下。
在请求被转发到回退的情况下,Spring Cloud 断路器网关过滤器还会提供导致它的 Throwable。它作为 ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR 属性添加到 ServerWebExchange 中,可以在网关应用程序中处理回退时使用。
对于外部控制器/处理器场景,可以添加带有异常详细信息的头部。您可以在 回退头部网关过滤器工厂部分中找到有关这样做的更多信息。
根据状态码触发断路器
在某些情况下,您可能希望根据从其包装的路由返回的状态码来触发断路器。断路器配置对象接受一个状态码列表,如果返回这些状态码,将导致断路器被触发。在设置您希望触发断路器的状态码时,您可以使用带有状态码值的整数或 HttpStatus 枚举的字符串表示。
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"
@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();
}