版本:2.0.2.RELEASE
链接:http://spring.io/projects/spring-cloud-gateway#overview
本章主要目录如下:
Spring Cloud Gateway网关过滤器工厂是什么?
本章主要内容如下:
Spring Cloud Gateway网关过滤器工厂是什么?
路由过滤器允许以某种方式修改传入的 HTTP 请求或输出的 HTTP 响应。路由过滤器作用于特定路由。Spring Cloud Gateway 包含许多内置的 GatewayFilter 工厂。
注意:有关如何使用下面的任何过滤器的更详细的示例,请看单元测试。
AddRequestHeader 网关过滤器工厂
添加请求头网关过滤器工厂可以在请求头中添加一对键值对参数。
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。
AddRequestParameter 网关过滤器工厂
添加请求参数网关过滤器工厂可以在请求中添加一对请求参数的键值对。
application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: http://example.org
filters:
- AddRequestParameter=foo, bar
这会将 foo=bar 添加到所有匹配请求的下游请求的查询字符串中。
AddResponseHeader 网关过滤器工厂
添加响应头网关过滤器工厂可以在响应头中添加键值对。
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 添加到所有匹配请求的下游响应头部中。
Hystrix 网关过滤器工厂
Hystrix 是 Netflix 的一个库,它实现了断路器模式。Hystrix 网关过滤器允许您将断路器引入到网关路由,保护您的服务免受级联故障的影响,并允许您在下游故障时提供回退响应。
要在项目中启用Hystrix 网关过滤器,请从Spring Cloud Netflix中添加spring-cloud-starter-netflix-hystrix依赖项。
Hystrix 网关过滤器需要一个名称参数,该参数是HystrixCommand 的名称。
application.yml
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: http://example.org
filters:
- Hystrix=myCommandName
这将使用命令名称 myCommandName 将剩余的过滤器包装在 HystrixCommand 中。
Hystrix过滤器还可以接受可选的fallbackUri参数。 目前,仅支持forward:schemed URIs。如果调用了回退,请求将被转发到与 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。请注意, 此示例还通过目标 URI 上的 lb 前缀演示(可选)Spring Cloud Netflix Ribbon 负载均衡。
Hystrix 设置(例如超时)可以使用全局默认值配置,也可以使用应用程序属性逐个路径配置,如 Hystrix wiki 中所述。
要为上面的示例路由设置 5 秒超时,将使用以下配置:
application.yml
hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
PrefixPath 网关过滤器工厂
PrefixPath 网关过滤器工厂使用的是一个简单的 prefix 参数。
application.yml
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: http://example.org
filters:
- PrefixPath=/mypath
这将使/mypath 为所有匹配请求的路径前缀。所以,向/hello 请求将被发送到/mypath/hello。
PreserveHostHeader 网关过滤器工厂
此网关过滤器工厂没有参数。此过滤器设置路由过滤器将检查的请求属性,以确定是否应发送原始主机头,而不是 http 客户端确定的主机头。
application.yml
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: http://example.org
filters:
- PreserveHostHeader
RequestRateLimiter 网关过滤器工厂
RequestRateLimiter 网关过滤器工厂使用 RateLimiter 实现来确定是否允许当前请求继续。如果不是,则返回 HTTP 429 - Too Many Requests(默认情况下)的状态。
此过滤器采用可选的 keyResolver 参数和特定于速率限制器的参数(参见下文)。
keyResolver 是一个实现 KeyResolver 接口的 bean。在配置中,使用 SpEL 按名称引用bean。#{@myKeyResolver}是一个引用名为myKeyResolver的bean的SpEL表达式。
KeyResolver.java
public interface KeyResolver {
Mono
}
KeyResolver 接口允许可插拔策略派生用于限制请求的密钥。在未来的里程碑中,将会有一些 KeyResolver 实现。
KeyResolver 的默认实现是 PrincipalNameKeyResolver,它从 ServerWebExchange 检索 Principal 并调用 Principal.getName()。
注意:RequestRateLimiter 不能通过“shortcut”表示法进行配置。以下示例无效。
application.properties.
# INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
-Redis 请求速率限制器
redis 实现基于 Stripe 完成的工作。它需要使用 spring-boot-starter-data-redis-reactive起步依赖。
使用的算法是令牌桶算法。
redis-rate-limiter.replenishRate:是您希望允许用户每秒执行多少请求,而不会丢弃任何请求。这是令牌桶填充的速率。
redis-rate-limiter.burstCapacity:是用户在一秒钟内允许执行的最大请求数。这是令牌桶可以容纳的令牌数。将此值设置为零将阻止所有请求。
通过在 replenishRate 和 burstCapacity 中设置相同的值来实现稳定的速率。通过将burstCapacity 设置为高于 replenishRate,可以允许临时突发。在这种情况下,需要在这段突发时间之间允许速率限制器(根据 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,但下一秒只有 10 个请求可用。KeyResolver 是一个简单的实现,它获取用户请求参数(注意:这不建议用于生产)。速率限制器也可以定义为实现 RateLimiter 接口的 bean。在配置中,使用 SpEL 按名称引用 bean。#{@myRateLimiter}是一个引用名为 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}"
RedirectTo 网关过滤器工厂
重定向过滤器工厂接受一个状态和一个 url 参数。该状态是一个 300 系列重定向 http代码,如 301。url 应该是有效的 url。这将是 Location 头部的值。
application.yml.
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: http://example.org
filters:
- RedirectTo=302, http://acme.org
将使用 Location:http://acme.org 标头发送状态 302 以执行重定向。
RemoveNonProxyHeaders 网关过滤器工厂
删除非代理头网关过滤器工厂从转发的请求中删除请求头。被删除的请求头的默认列表来自 IETF。
默认删除的请求头是:
Connection
Keep-Alive
Proxy-Authenticate
Proxy-Authorization
TE
Trailer
Transfer-Encoding
Upgrade
要更改此设置,请将 spring.cloud.gateway.filter.remove-non-proxy-headers.headers属性设置为要删除的标头名称列表。
RemoveRequestHeader 网关过滤器工厂
删除请求头网关过滤器工厂需要一个名称的参数,这个名称参数是需要删除的请求头名。
application.yml.
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: http://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
这将在向下游发送之前删除 X-Request-Foo 请求头。
RemoveResponseHeader 网关过滤器工厂
删除响应头网关过滤器工厂需要一个名称的参数,这个名称参数是需要删除的响应头名。
application.yml.
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: http://example.org
filters:
- RemoveResponseHeader=X-Response-Foo
将在返回到网关客户端之前从响应中删除 X-Response-Foo 头。
RewritePath 网关过滤器工厂
RewritePath 网关过滤器工厂采用路径正则表达式参数和一个替换参数。使用 Java 正
则表达式灵活地重写请求路径。
application.yml.
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://example.org
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?
对于/foo/bar 的请求路径,将在生成下游请求之前设置路径为/bar。注意,由于 YAML 规范,”$\” 被 “$” 替换。
SaveSession 网关过滤器工厂
SaveSession 网关过滤器工厂在转发下游调用之前强制执行 WebSession::save 操作。当使用诸如 Spring Session 之类的带有 lazy 数据存储的东西时,这是特别有用的,并且需要在进行转发调用之前确保会话状态已被保存。
application.yml.
spring:
cloud:
gateway:
routes:
- id: save_session
uri: http://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession
如果您正在将 Spring Security 和 Spring Session 集成,并且希望确保安全细节已经转发到远程进程,那么这是至关重要的。
SecureHeaders 网关过滤器工厂
安全头网关过滤器工厂在此博客文章(https://blog.appcanary.com/2017/http-security-headers.html)的推荐中为响应添加了许多标题。
添加了以下标头(默认值):
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 命名空间中设置相应的属性:
要更改的属性:
xss-protection-header
strict-transport-security
frame-options
content-type-options
referrer-policy
content-security-policy
download-options
permitted-cross-domain-policies
SetPath 网关过滤器工厂
设置路径网关过滤器工厂采用路径模板参数。它提供了一种通过允许路径的模板段来操作请求路径的简单方法。这使用了来自 Spring 框架的 URI 模板。允许多个匹配段。
application.yml.
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: http://example.org
predicates:
- Path=/foo/{segment}
filters:
- SetPath=/{segment}
对于/foo/bar 的请求路径,这将在进行下游请求之前将路径设置为/bar。
SetResponseHeader 网关过滤器工厂
设置响应头网关过滤器工厂需要参数名和参数的值的键值对参数。
application.yml.
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: http://example.org
filters:
- SetResponseHeader=X-Response-Foo, Bar
这个网关过滤器将给定的名称对应响应头的值替换掉原来请求响应头的值,注意不是添加而是替换。 因此,如果下游服务器用 X-Response-Foo:1234 响应,则将被X-Response-Foo:Bar 替代,网关客户端将收到的响应头为 X-Response-Foo:Bar 而不是X-Response-Foo:1234。
SetStatus 网关过滤器工厂
设置请求响应状态网关过滤器工厂需要一个 status 参数。该参数值必须是一个有效的Spring HttpStatus。该值可以是整型 404 或者是表示枚举类型 NOT_FOUND 的字符串。
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。
StripPrefix 网关过滤器工厂
剥离前缀网关过滤器工厂需要一个 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
Retry 网关过滤器工厂
重试网关过滤器工厂需要 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 的重试过滤器时,应仔细编写目标端点,以便在出现错误时不会执行任何可能导致响应发送到客户端并提交的操作。例如,如果目标端点是带注释的控制器,则目标控制器方法不应返回ResponseEntity错误状态代码。相反,它应该抛出一个Exception或发出错误信号,例如通过Mono.error(ex)返回值,重试过滤器可以配置为通过重试来处理。这里是不是可以理解使用前向协议的 URI 不支持使用重试过滤器。
//2.1.0.M3版本新增该过滤器,在这里我们也做一下了解
RequestSize 网关过滤器工厂
当请求大小大于允许的限制时,RequestSize 网关过滤器可以限制请求到达下游服务。过滤器RequestSize作为参数,该参数是以字节为单位定义的请求的允许大小限制。
application.yml。
spring:
cloud:
gateway:
routes:
- id:request_size_route
uri:http:// localhost:8080 / upload
predicates:
- Path = / upload
filters:
- name:RequestSize
args:
maxSize:5000000
当请求因大小而被拒绝时,RequestSize 网关过滤器将响应状态设置为 413 Payload Too Large(有效负载太大),并附加标头 errorMessage。以下是此类 errorMessage 的示例。
errorMessage : 请求大小大于允许的限制。请求大小为 6.0 MB,允许的限制为 5.0 MB。
注意:如果未在路由定义中提供过滤器参数,则默认请求大小将设置为5 MB。
如有疑惑,关注公众号获取更多内容,下一章将一起讨论全局过滤器。