Retry 过滤器

Retry 过滤器会根据类路径中可用的内容自动选择合适的重试实现。

  • 如果 Spring Retry 在类路径中,过滤器默认使用 GatewayRetryFilterFunctions(基于 Spring Retry)。

  • 如果 Spring Retry 不在类路径中,过滤器会自动使用 FrameworkRetryFilterFunctions(基于 Spring Framework 7 中的重试功能)。

Spring Retry 已进入仅维护模式。一旦 Spring Retry 不再维护,Retry 过滤器将专门使用 Framework 重试实现(FrameworkRetryFilterFunctions),并且基于 Spring Retry 的实现将被移除。
即使 Spring Retry 在类路径中,您也可以通过在配置中设置 spring.cloud.gateway.server.webmvc.use-framework-retry-filter=true 来强制使用 Framework 重试过滤器。

Retry 过滤器支持以下参数:

  • retries:应尝试的重试次数。

  • methods:应重试的 HTTP 方法,使用 org.springframework.http.HttpMethod 表示。

  • series:应重试的状态码系列,使用 org.springframework.http.HttpStatus.Series 表示。

  • exceptions:应重试的抛出异常列表。

  • cacheBody:一个标志,指示是否应缓存请求体。如果设置为 true,则必须使用 adaptCacheBody 过滤器将缓存的请求体发送到下游。

如果启用,Retry 过滤器配置了以下默认值:

  • retries:三次

  • series:5XX 系列

  • methods:GET 方法

  • exceptionsIOExceptionTimeoutExceptionRetryException

  • cacheBodyfalse

cacheBody 设置为 true 会导致网关将整个请求体读入内存。应谨慎使用此功能。

以下清单配置了一个 Retry 过滤器:

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: retry_route
          uri: https://:8080/flakey
          predicates:
          - Host=*.retry.com
          filters:
          - name: Retry
            args:
              retries: 3
              series: SERVER_ERROR
              methods: GET,POST
              cacheBody: true
          - name: AdaptCachedBody
GatewaySampleApplication.java
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
import static org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions.adaptCachedBody;
import static org.springframework.cloud.gateway.server.mvc.filter.RetryFilterFunctions.retry;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.host;

@Configuration
class RouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> gatewayRouterFunctionsRetry() {
        return route("retry_route")
            .route(host("*.retry.com"), http())
            .before(uri("https://:8080/flakey"))
            .filter(retry(config -> config.setRetries(3)
                    .setSeries(Set.of(HttpStatus.Series.SERVER_ERROR))
                    .setMethods(Set.of(HttpMethod.GET, HttpMethod.POST))
                    .setCacheBody(true)))
            .filter(adaptCachedBody())
            .build();
    }
}
当使用带有 forward: 前缀 URL 的重试过滤器时,目标端点应仔细编写,以便在发生错误时,它不会执行任何可能导致响应发送到客户端并提交的操作。例如,如果目标端点是一个带注解的控制器,则目标控制器方法不应返回带有错误状态码的 ResponseEntity。相反,它应该抛出 Exception 或发出错误信号(例如,通过 Mono.error(ex) 返回值),重试过滤器可以配置为通过重试来处理此错误。
当使用重试过滤器时,它将重试其之后的所有过滤器。请确保重试过滤器之后的过滤器在多次执行时其结果符合预期。
当使用重试过滤器与任何带有请求体且 cacheBody=true 的 HTTP 方法时,请求体将被缓存,网关将受到内存限制。请求体缓存在由 MvcUtils.CACHED_REQUEST_BODY_ATT 定义的请求属性中。对象的类型为 ByteArrayInputStream

可以使用单个 statusmethod 添加简化的“快捷方式”表示法。

以下两个示例路由是等效的:

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: retry_route
          uri: https://example.org
          filters:
          - name: Retry
            args:
              retries: 3
              statuses: INTERNAL_SERVER_ERROR
              methods: GET
        - id: retryshortcut_route
          uri: https://example.org
          filters:
          - Retry=3,INTERNAL_SERVER_ERROR,GET

强制使用 Framework 重试过滤器

当 Spring Retry 在类路径中时,Retry 过滤器默认使用基于 Spring Retry 的实现。要强制使用 Framework 重试过滤器,请设置以下属性:

application.yml
spring:
  cloud:
    gateway:
      server:
        webmvc:
          use-framework-retry-filter: true
application.properties
spring.cloud.gateway.server.webmvc.use-framework-retry-filter=true
© . This site is unofficial and not affiliated with VMware.