Retry 过滤器
Retry Filter
Retry 过滤器会根据类路径上可用的实现自动选择合适的重试实现:
-
如果类路径中存在 Spring Retry,过滤器默认使用
GatewayRetryFilterFunctions(基于 Spring Retry)。 -
如果类路径中不存在 Spring Retry,过滤器会自动使用
FrameworkRetryFilterFunctions(基于 Spring Framework 7 中的重试功能)。
Spring Retry 已进入仅维护模式。一旦 Spring Retry 停止维护,Retry 过滤器将完全使用框架的重试实现(FrameworkRetryFilterFunctions),而基于 Spring Retry 的实现将被移除。
即使类路径上存在 Spring Retry,你也可以通过在配置中设置 spring.cloud.gateway.server.webmvc.use-framework-retry-filter=true 来强制使用框架的重试过滤器。
Retry 过滤器支持以下参数:
-
retries: 应尝试的重试次数。 -
methods: 应重试的 HTTP 方法,使用org.springframework.http.HttpMethod表示。 -
series: 应重试的状态码系列,使用org.springframework.http.HttpStatus.Series表示。 -
exceptions: 应重试的抛出异常列表。 -
cacheBody: 标志是否应缓存请求体。如果设置为true,则必须使用adaptCacheBody过滤器将缓存的请求体发送到下游。
如果启用了 Retry 过滤器,将配置以下默认值:
-
retries: 三次 -
series: 5XX 系列 -
methods: GET 方法 -
exceptions:IOException、TimeoutException和RetryException -
cacheBody:false
将 cacheBody 设置为 true 会导致网关将整个请求体读入内存。请谨慎使用此设置。
以下配置展示了一个重试过滤器:
spring:
cloud:
gateway:
server:
webmvc:
routes:
- id: retry_route
uri: http://localhost:8080/flakey
predicates:
- Host=*.retry.com
filters:
- name: Retry
args:
retries: 3
series: SERVER_ERROR
methods: GET,POST
cacheBody: true
- name: AdaptCachedBody
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("http://localhost: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) 返回值),重试过滤器可以配置为通过重试来处理这种情况。
使用重试过滤器时,它会重试其后的所有过滤器。请确保重试过滤器之后的过滤器在多次执行时,其结果符合预期。
当使用重试过滤器配合任何带有请求体的 HTTP 方法,且 cacheBody=true 时,请求体将被缓存,这可能导致网关内存受限。请求体会缓存在由 MvcUtils.CACHED_REQUEST_BODY_ATT 定义的请求属性中。该对象的类型为 ByteArrayInputStream。
可以添加一个简化的“快捷”表示法,使用单个 status 和 method。
以下两条示例路由是等价的:
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
强制框架重试过滤器
当 Spring Retry 位于类路径上时,Retry 过滤器默认使用基于 Spring Retry 的实现。要强制使用框架的重试过滤器,请设置以下属性:
spring:
cloud:
gateway:
server:
webmvc:
use-framework-retry-filter: true
spring.cloud.gateway.server.webmvc.use-framework-retry-filter=true