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.