115. GatewayFilter 工厂
Route 过滤器允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。 Route 过滤器的范围限定为特定的 route。 Spring Cloud Gateway 包含许多 built-in GatewayFilter 工厂。
注意有关如何使用以下任何过滤器的更多详细示例,请查看单元测试。
115.1 AddRequestHeader GatewayFilter Factory
AddRequestHeader GatewayFilter Factory 采用 name 和 value 参数。
application.yml.
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: http://example.org
filters:
- AddRequestHeader=X-Request-Foo, Bar
这将为所有匹配的请求将X-Request-Foo:Bar
标头添加到下游请求的 headers。
115.2 AddRequestParameter GatewayFilter Factory
AddRequestParameter GatewayFilter Factory 采用 name 和 value 参数。
application.yml.
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: http://example.org
filters:
- AddRequestParameter=foo, bar
这将为所有匹配的请求将foo=bar
添加到下游请求的查询 string。
115.3 AddResponseHeader GatewayFilter Factory
AddResponseHeader GatewayFilter Factory 采用 name 和 value 参数。
application.yml.
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: http://example.org
filters:
- AddResponseHeader=X-Response-Foo, Bar
这将为所有匹配的请求将X-Response-Foo:Bar
标头添加到下游响应的 headers。
115.4 Hystrix GatewayFilter Factory
Hystrix是来自 Netflix 的 library,它实现了断路器 pattern。 Hystrix GatewayFilter 允许您将断路器引入网关 routes,保护您的服务免受级联故障的影响,并允许您在下游故障发生时提供回退响应。
要在项目中启用 Hystrix GatewayFilters,请从Spring Cloud Netflix添加对spring-cloud-starter-netflix-hystrix
的依赖关系。
Hystrix GatewayFilter Factory 需要一个name
参数,即HystrixCommand
的 name。
application.yml.
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: http://example.org
filters:
- Hystrix=myCommandName
这将使用 name myCommandName
命令将剩余的过滤器包装在HystrixCommand
中。
Hystrix 过滤器也可以接受可选的fallbackUri
参数。目前,仅支持forward:
计划的 URI。如果调用了回退,则请求将被转发到与 URI 匹配的控制器。
application.yml.
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingserviceendpoint
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/incaseoffailureusethis
- RewritePath=/consumingserviceendpoint, /backingserviceendpoint
当调用 Hystrix 回退时,这将转发到/incaseoffailureusethis
URI。请注意,此 example 还通过目标 URI 上的lb
前缀演示(可选)Spring Cloud Netflix Ribbon load-balancing。
Hystrix 设置(例如超时)可以使用 global 默认值配置,也可以使用 application properties 基于 route 配置,如Hystrix wiki所述。
要为上面的 example route 设置 5 秒超时,将使用以下 configuration:
application.yml.
hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
115.5 PrefixPath GatewayFilter Factory
PrefixPath GatewayFilter Factory 采用单个prefix
参数。
application.yml.
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: http://example.org
filters:
- PrefixPath=/mypath
这将/mypath
前缀到所有匹配请求的路径。因此,对/hello
的请求将被发送到/mypath/hello
。
115.6 PreserveHostHeader GatewayFilter Factory
PreserveHostHeader GatewayFilter Factory 没有参数。此过滤器设置路由过滤器将检查的请求属性,以确定是否应发送原始 host 标头,而不是 http client 确定的 host 标头。
application.yml.
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: http://example.org
filters:
- PreserveHostHeader
115.7 RequestRateLimiter GatewayFilter Factory
RequestRateLimiter GatewayFilter Factory 使用RateLimiter
implementation 来确定是否允许当前请求继续。如果不是,则返回HTTP 429 - Too Many Requests
(默认情况下)的状态。
此过滤器采用可选的keyResolver
参数和特定于速率限制器的参数(参见下文)。
keyResolver
是实现KeyResolver
接口的 bean。在 configuration 中,使用 SpEL 通过 name 引用 bean。 #{@myKeyResolver}
是一个引用带有 name myKeyResolver
的 bean 的 SpEL 表达式。
KeyResolver.java.
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
KeyResolver
接口允许可插拔策略派生 key 以限制请求。在未来的里程碑中,会有一些KeyResolver
__mplement。
KeyResolver
的默认_imple 是PrincipalNameKeyResolver
,它从ServerWebExchange
和 calls Principal.getName()
中检索Principal
。
RequestRateLimiter 不能通过“快捷方式”表示法进行配置。以下示例无效
application.properties.
# INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
115.7.1 Redis RateLimiter
redis implementation 基于条纹完成的工作。它需要使用spring-boot-starter-data-redis-reactive
Spring Boot starter。
使用的算法是令牌桶算法。
redis-rate-limiter.replenishRate
是您希望允许用户每秒执行多少请求,而不会丢弃任何请求。这是令牌桶填充的速率。
redis-rate-limiter.burstCapacity
是用户在一秒钟内允许执行的最大请求数。这是令牌桶可以容纳的令牌数。将此 value 设置为零将阻止所有请求。
通过在replenishRate
和burstCapacity
中设置相同的 value 来实现稳定的速率。通过将burstCapacity
设置为高于replenishRate
,可以允许临时突发。在这种情况下,需要在突发之间允许速率限制器一些 time(根据replenishRate
),因为 2 个连续突发将导致请求被丢弃(HTTP 429 - Too Many Requests
)。
application.yml.
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: http://example.org
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
Config.java.
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
这定义了每个用户 10 的请求率限制。允许使用 20 的 burst,但下一秒只有 10 个请求可用。 KeyResolver
是一个简单的获取user
请求参数(注意:这不建议用于 production)。
速率限制器也可以定义为实现RateLimiter
接口的 bean。在 configuration 中,使用 SpEL 通过 name 引用 bean。 #{@myRateLimiter}
是一个引用带有 name myRateLimiter
的 bean 的 SpEL 表达式。
application.yml.
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: http://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"
115.8 RedirectTo GatewayFilter Factory
RedirectTo GatewayFilter Factory 采用status
和url
参数。状态应该是 300 系列重定向 http code,例如 301. url 应该是有效的 URL。这将是Location
标题的 value。
application.yml.
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: http://example.org
filters:
- RedirectTo=302, http://acme.org
这将发送带有Location:http://acme.org
标头的状态 302 以执行重定向。
115.9 RemoveNonProxyHeaders GatewayFilter Factory
RemoveNonProxyHeaders GatewayFilter Factory 从转发的请求中删除 headers。删除的_header 的默认列表来自IETF。
默认删除的 headers 是:
-
连接
-
Keep-Alive
-
Proxy-Authenticate
-
Proxy-Authorization
-
TE
-
预告片
-
Transfer-Encoding
-
升级
要更改此设置,请将spring.cloud.gateway.filter.remove-non-proxy-headers.headers
property 设置为要删除的标题名称列表。
115.10 RemoveRequestHeader GatewayFilter Factory
RemoveRequestHeader GatewayFilter Factory 采用name
参数。它是要删除的标头的 name。
application.yml.
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: http://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
这将在向下游发送之前删除X-Request-Foo
标头。
115.11 RemoveResponseHeader GatewayFilter Factory
RemoveResponseHeader GatewayFilter Factory 采用name
参数。它是要删除的标头的 name。
application.yml.
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: http://example.org
filters:
- RemoveResponseHeader=X-Response-Foo
这将在响应返回到网关 client 之前从响应中删除X-Response-Foo
标头。
115.12 RewritePath GatewayFilter Factory
RewritePath GatewayFilter Factory 采用路径regexp
参数和replacement
参数。这使用 Java 正则表达式以灵活的方式来编写请求路径。
application.yml.
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://example.org
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?<segment>.*), /$\{segment}
对于/foo/bar
的请求路径,这将在发出下游请求之前将路径设置为/bar
。请注意$\
由于 YAML 规范而被$
替换。
115.13 SaveSession GatewayFilter Factory
SaveSession GatewayFilter Factory 在转发下游呼叫之前强制执行WebSession::save
操作。当使用Spring Session这样的东西与惰性数据 store 时,这是特别有用的,并且需要确保在转发调用之前已保存 session state。
application.yml.
spring:
cloud:
gateway:
routes:
- id: save_session
uri: http://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession
如果要将Spring Security与 Spring Session 集成,并希望确保安全性详细信息已转发到 remote process,则这很关键。
115.14 SecureHeaders GatewayFilter Factory
SecureHeaders GatewayFilter Factory 在这篇博文的 reccomendation 中为响应添加了许多 headers。
添加以下_header(默认值为 allong):
-
X-Xss-Protection:1; mode=block
-
Strict-Transport-Security:max-age=631138519
-
X-Frame-Options:DENY
-
X-Content-Type-Options:nosniff
-
Referrer-Policy:no-referrer
-
Content-Security-Policy:default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
-
X-Download-Options:noopen
-
X-Permitted-Cross-Domain-Policies:none
要更改默认值,请在spring.cloud.gateway.filter.secure-headers
命名空间中设置相应的 property:
要更改的财产:
-
xss-protection-header
-
strict-transport-security
-
frame-options
-
content-type-options
-
referrer-policy
-
content-security-policy
-
download-options
-
permitted-cross-domain-policies
115.15 SetPath GatewayFilter Factory
SetPath GatewayFilter Factory 采用路径template
参数。它提供了一种通过允许模板化路径段来操作请求路径的简单方法。这使用 Spring Framework 中的 uri 模板。允许多个匹配的段。
application.yml.
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: http://example.org
predicates:
- Path=/foo/{segment}
filters:
- SetPath=/{segment}
对于/foo/bar
的请求路径,这将在发出下游请求之前将路径设置为/bar
。
115.16 SetResponseHeader GatewayFilter Factory
SetResponseHeader GatewayFilter Factory 采用name
和value
参数。
application.yml.
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: http://example.org
filters:
- SetResponseHeader=X-Response-Foo, Bar
此 GatewayFilter 用给定的 name 替换所有_header,而不是添加。因此,如果下游服务器以X-Response-Foo:1234
响应,则将替换为X-Response-Foo:Bar
,这是网关客户端将接收的内容。
115.17 SetStatus GatewayFilter Factory
SetStatus GatewayFilter Factory 采用单个status
参数。它必须是有效的 Spring HttpStatus
。它可能是 integer value 404
或枚举NOT_FOUND
的 string 表示。
application.yml.
spring:
cloud:
gateway:
routes:
- id: setstatusstring_route
uri: http://example.org
filters:
- SetStatus=BAD_REQUEST
- id: setstatusint_route
uri: http://example.org
filters:
- SetStatus=401
在任何一种情况下,响应的 HTTP 状态都将设置为 401。
115.18 StripPrefix GatewayFilter Factory
StripPrefix GatewayFilter Factory 需要一个参数parts
。 parts
参数指示在向下游发送之前从请求中剥离的路径中的部分数。
application.yml.
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: http://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
当通过网关向/name/bar/foo
发出请求时,对nameservice
的请求将看起来像http://nameservice/foo
。
115.19 重试 GatewayFilter Factory
Retry GatewayFilter Factory 将retries
,statuses
,methods
和series
作为参数。
-
retries
:应尝试的重试次数 -
statuses
:应重试的 HTTP 状态代码,使用org.springframework.http.HttpStatus
表示 -
methods
:应该重试的 HTTP 方法,使用org.springframework.http.HttpMethod
表示 -
series
:要重试的一系列状态代码,使用org.springframework.http.HttpStatus.Series
表示
application.yml.
spring:
cloud:
gateway:
routes:
- id: retry_test
uri: http://localhost:8080/flakey
predicates:
- Host=*.retry.com
filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY
当使用带有
forward:
前缀 URL 的重试过滤器时,应仔细编写目标端点,以便在出现错误时不会执行任何可能导致响应发送到 client 并提交的操作。例如,如果目标端点是带注释的控制器,则目标控制器方法不应相反,它应该抛出Exception
,或发出错误信号 e.g. 通过Mono.error(ex)
return value,可以将重试过滤器配置为通过重试来处理。