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

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

要配置断路器,请参阅您正在使用的底层断路器实现的配置。

Spring Cloud 断路器过滤器还可以接受一个可选的 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 前缀定义)。

断路器还支持 fallbackUri 中的 URI 变量。这允许更复杂的路由选项,例如使用 PathPattern 表达式转发原始主机或 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: https://:9994
        predicates:
        - Path=/fallback

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

在请求被转发到回退的情况下,Spring Cloud 断路器网关过滤器还会提供导致它的 Throwable。它作为 ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR 属性添加到 ServerWebExchange 中,可以在网关应用程序中处理回退时使用。

对于外部控制器/处理器场景,可以添加带有异常详细信息的头部。您可以在 回退头部网关过滤器工厂部分中找到有关这样做的更多信息。

根据状态码触发断路器

在某些情况下,您可能希望根据从其包装的路由返回的状态码来触发断路器。断路器配置对象接受一个状态码列表,如果返回这些状态码,将导致断路器被触发。在设置您希望触发断路器的状态码时,您可以使用带有状态码值的整数或 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();
}
© . This site is unofficial and not affiliated with VMware.