1、Predicate
Predicate来自于java8的接口(断定式接口)。Predicate接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非)。可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。add–与、or–或、negate–非
1)After
After Route Predicate Factory使用的是时间作为匹配规则,只要当前时间大于设定时间,路由才会匹配请求
spring:
cloud:
gateway:
routes:
- id: after_route
uri: http://www.google.com
predicates:
- After=2018-12-25T14:33:47.789+08:00
这个路由规则会在东8区的2018-12-25 14:33:47后,将请求都转跳到google。
2)Before
Before Route Predicate Factory也是使用时间作为匹配规则,只要当前时间小于设定时间,路由才会匹配请求
spring:
cloud:
gateway:
routes:
- id: before_route
uri: http://www.google.com
predicates:
- Before=2018-12-25T14:33:47.789+08:00
这个路由规则会在东8区的2018-12-25 14:33:47前,将请求都转跳到google
3)Between
Between Route Predicate Factory也是使用两个时间作为匹配规则,只要当前时间大于第一个设定时间,并小于第二个设定时间,路由才会匹配请求
spring:
cloud:
gateway:
routes:
- id: between_route
uri: http://www.google.com
predicates:
- Between=2018-12-25T14:33:47.789+08:00, 2018-12-26T14:33:47.789+08:00
这个路由规则会在东8区的2018-12-25 14:33:47到2018-12-26 14:33:47之间,将请求都转跳到google
4)Cookie
Cookie Route Predicate Factory使用的是cookie名字和正则表达式的value作为两个输入参数,请求的cookie需要匹配cookie名和符合其中value的正则
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://www.google.com
predicates:
- Cookie=cookiename, cookievalue
路由匹配请求存在cookie名为cookiename,cookie内容匹配cookievalue的,将请求转发到google
5)Header
Header Route Predicate Factory,与Cookie Route Predicate Factory类似,也是两个参数,一个header的name,一个是正则匹配的value
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://www.google.com
predicates:
- Header=X-Request-Id, \d+
路由匹配存在名为
X-Request-Id
,内容为数字的header的请求,将请求转发到google
6)Host
Host Route Predicate Factory使用的是host的列表作为参数,host使用Ant style匹配
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://www.google.com
predicates:
- Host=**.somehost.org,**.anotherhost.org
路由会匹配Host诸如:
www.somehost.org
或beta.somehost.org
或www.anotherhost.org
等请求
7)Method
Method Route Predicate Factory是通过HTTP的method来匹配路由
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://www.google.com
predicates:
- Method=GET
路由会匹配到所有GET方法的请求
8)Path
Path Route Predicate Factory使用的是path列表作为参数,使用Spring的
PathMatcher
匹配path,可以设置可选变量
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://www.google.com
predicates:
- Path=/foo/{segment},/bar/{segment}
上面路由可以匹配诸如:
/foo/1
或/foo/bar
或/bar/baz
等
9)Query
Query Route Predicate Factory可以通过一个或两个参数来匹配路由,一个是查询的name,一个是查询的正则value
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://www.google.com
predicates:
- Query=baz
路由会匹配所有包含
baz
查询参数的请求
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://www.google.com
predicates:
- Query=foo, ba.
路由会匹配所有包含
foo
,并且foo
的内容为诸如:bar
或baz
等符合ba.
正则规则的请求
10)RemoteAddr
RemoteAddr Route Predicate Factory通过无类别域间路由(IPv4 or IPv6)列表匹配路由
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: http://www.google.com
predicates:
- RemoteAddr=192.168.1.1/24
上面路由就会匹配RemoteAddr诸如
192.168.1.10
等请求
2、Filter
Route filters可以通过一些方式修改HTTP请求的输入和输出,针对某些特殊的场景,Spring Cloud Gateway已经内置了很多不同功能的GatewayFilter Factories。
1)AddRequestHeader
AddRequestHeader GatewayFilter Factory通过配置name和value可以增加请求的header
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: http://www.google.com
filters:
- AddRequestHeader=X-Request-Foo, Bar
对匹配的请求,会额外添加
X-Request-Foo:Bar
的header
2)AddRequestParameter
AddRequestParameter GatewayFilter Factory通过配置name和value可以增加请求的参数
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: http://www.google.com
filters:
- AddRequestParameter=foo, bar
对匹配的请求,会额外添加
foo=bar
的请求参数
3)AddResponseHeader
AddResponseHeader GatewayFilter Factory通过配置name和value可以增加响应的header
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: http://www.google.com
filters:
- AddResponseHeader=X-Response-Foo, Bar
对匹配的请求,响应返回时会额外添加
X-Response-Foo:Bar
的header返回
4)Hystrix
Hystrix是Netflix实现的断路器模式工具包,The Hystrix GatewayFilter就是将断路器使用在gateway的路由上,目的是保护你的服务避免级联故障,以及在下游失败时可以降级返回
项目里面引入
spring-cloud-starter-netflix-hystrix
依赖,并提供HystrixCommand
的名字,即可生效Hystrix GatewayFilter
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: http://www.google.com
filters:
- Hystrix=myCommandName
那么剩下的过滤器,就会包装在名为myCommandName的HystrixCommand中运行。
Hystrix过滤器也是通过配置参数fallbackUri,来支持路由熔断后的降级处理,降级后,请求会跳过fallbackUri配置的路径,目前只支持forward:的URI协议
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingserviceendpoint
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/incaseoffailureusethis
当Hystrix降级后就会将请求转发到/incaseoffailureusethis
。
整个流程其实是用fallbackUri
将请求跳转到gateway内部的controller或者handler,然而也可以通过以下的方式将请求转发到外部的服务
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: Hystrix
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
以上的例子,gateway降级后就会将请求转发到http: //localhost:9994。
Hystrix Gateway filter在转发降级请求时,会将造成降级的异常设置在ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR属性中,在处理降级时也可以用到。
比如下一节讲到的FallbackHeaders GatewayFilter Factory,就会通过上面的方式拿到异常信息,设置到降级转发请求的header上,来告知降级下游异常信息。
通过下面配置可以设置Hystrix的全局超时信息
hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
5)FallbackHeaders
FallbackHeaders GatewayFilter Factory可以将Hystrix执行的异常信息添加到外部请求的
fallbackUri
header上
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: Hystrix
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Test-Header
在这个例子中,当请求lb://ingredients
降级后,FallbackHeaders
filter会将HystrixCommand
的异常信息,通过Test-Header
带给http://localhost:9994
服务。
你也可以使用默认的header,也可以像上面一下配置修改header的名字:
- executionExceptionTypeHeaderName (“Execution-Exception-Type”)
- executionExceptionMessageHeaderName (“Execution-Exception-Message”)
- rootCauseExceptionTypeHeaderName (“Root-Cause-Exception-Type”)
- rootCauseExceptionMessageHeaderName (“Root-Cause-Exception-Message”)
6)PrefixPath
The PrefixPath GatewayFilter Factory通过设置
prefix
参数来添加路径前缀
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: http://www.google.com
filters:
- PrefixPath=/mypath
如果一个请求是
/hello
,通过上面路由,就会将请求修改为/mypath/hello
7)PreserveHostHeader
PreserveHostHeader GatewayFilter Factory会保留原始请求的
host
头信息,并原封不动的转发出去,而不是被gateway的http客户端重置
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: http://www.google.com
filters:
- PreserveHostHeader
8)RequestRateLimiter
RequestRateLimiter GatewayFilter Factory使用
RateLimiter
来决定当前请求是否允许通过,如果不允许,则默认返回状态码HTTP 429 - Too Many Requests
RequestRateLimiter GatewayFilter可以使用一个可选参数keyResolver来做速率限制。
keyResolver是KeyResolver接口的一个实现bean,在配置里面,通过SpEL表达式#{@myKeyResolver}来管理bean的名字myKeyResolver
- KeyResolver.java
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
KeyResolver接口允许你使用不同的策略来得出限制请求的key,未来,官方也会推出一些KeyResolver的不同实现。
KeyResolver默认实现是PrincipalNameKeyResolver,通过ServerWebExchange中获取Principal,并以Principal.getName()作为限流的key。
如果KeyResolver拿不到key,请求默认都会被限制,你也可以自己配置spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key
:是否允许空key
spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code
:空key时返回的状态码。
RequestRateLimiter不支持捷径配置,如下面的配置是非法的
# INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
9)RedirectTo
RedirectTo GatewayFilter Factory使用
status
和url
两个参数,其中status
必须是300系列的HTTP状态码,url
则是跳转的地址,会放在响应的Location
的header中(http协议中转跳的header)
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: http://www.google.cn
filters:
- RedirectTo=302, http://www.edjdhbb.com
上面路由会执行302重定向到 http : //www. edjdhbb.com
10)RemoveNonProxyHeaders
RemoveNonProxyHeaders GatewayFilter Factory转发请求是会根据IETF的定义,默认会移除下列的http头信息:
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- TE
- Trailer
- Transfer-Encoding
- Upgrade
你也可以通过配置
spring.cloud.gateway.filter.remove-non-proxy-headers.headers
来更改需要移除的header列表
11)RemoveRequestHeader
RemoveRequestHeader GatewayFilter Factory配置header的name,即可以移除请求的header
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: http://www.google.com
filters:
- RemoveRequestHeader=X-Request-Foo
上面路由在发送请求给下游时,会将请求中的
X-Request-Foo
头信息去掉
12)RemoveResponseHeader
RemoveResponseHeader GatewayFilter Factory通过配置header的name,会在响应返回时移除header
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: http://www.google.com
filters:
- RemoveResponseHeader=X-Response-Foo
上面路由会在响应返回给gateway的客户端时,将
X-Response-Foo
响应头信息去掉
13)RewritePath
RewritePath GatewayFilter Factory使用路径
regexp
和替换路径replacement
两个参数做路径重写,两个都可以灵活地使用java的正则表达式
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://www.google.com
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?<segment>.*), /$\{segment}
对于上面的例子,如果请求的路径是
/foo/bar
,则gateway会将请求路径改为/bar
发送给下游。
注:在YAML 的格式中使用
$\
来代替$
。
14)RewriteResponseHeader
RewriteResponseHeader GatewayFilter Factory的作用是修改响应返回的header内容,需要配置响应返回的header的
name
,匹配规则regexp
和替换词replacement
,也是支持java的正则表达式
spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: http://www.google.com
filters:
- RewriteResponseHeader=X-Response-Foo, , password=[^&]+, password=***
举个例子,对于上面的filter,如果响应的headerX-Response-Foo的内容是/42?user=ford&password=omg!what&flag=true,这个内容会修改为/42?user=ford&password=***&flag=true
15)SaveSession
SaveSession GatewayFilter Factory会在请求下游时强制执行
WebSession::save
方法,用在那种像Spring Session
延迟数据存储的,并在请求转发前确保session状态保存情况
spring:
cloud:
gateway:
routes:
- id: save_session
uri: http://www.google.com
predicates:
- Path=/foo/**
filters:
- SaveSession
如果你将
Spring Secutiry
于Spring Session
集成使用,并想确保安全信息都传到下游机器,你就需要配置这个filter
16)SecureHeaders
SecureHeaders GatewayFilter Factory会添加在返回响应中一系列安全作用的header
默认会添加这些头信息和默认内容:
- 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
上面的header对应的后缀:
- xss-protection-header
- strict-transport-security
- frame-options
- content-type-options
- referrer-policy
- content-security-policy
- download-options
- permitted-cross-domain-policies
前后缀接起来即可,如:spring.cloud.gateway.filter.secure-headers.xss-protection-header
17)SetPath
SetPath GatewayFilter Factory采用路径
template
参数,通过请求路径的片段的模板化,来达到操作修改路径的目的,运行多个路径片段模板化
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: http://www.google.com
predicates:
- Path=/foo/{segment}
filters:
- SetPath=/{segment}
对于上面的例子,如果路径是
/foo/bar
,则对于下游的请求路径会修改为/bar
18)SetResponseHeader
SetResponseHeader GatewayFilter Factory通过设置
name
和value
来替换响应返回的header
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: http://www.google.com
filters:
- SetResponseHeader=X-Response-Foo, Bar
对于上面的例子,如果下游的返回带有头信息为
X-Response-Foo:1234
,则gateway会替换为X-Response-Foo:Bar
,再返回给客户端
19)SetStatus
SetStatus GatewayFilter Factory通过配置有效的Spring
HttpStatus
枚举参数,可以是类似于404的这些数字,也可以是枚举的name字符串,来修改响应的返回码
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: http://www.google.com
filters:
- SetResponseHeader=X-Response-Foo, Bar
上面例子中,两种路由都会将响应的状态码设置为401
20)StripPrefix
StripPrefix GatewayFilter Factory通过配置
parts
来表示截断路径前缀的数量
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: http://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
如上面例子中,如果请求的路径为
/name/bar/foo
,则路径会修改为/foo
,即将路径的两个前缀去掉了
21)Retry
Retry GatewayFilter Factory可以配置针对不同的响应做请求重试,可以配置如下参数:
- retries: 重试次数
- statuses: 需要重试的状态码,需要根据枚举 org.springframework.http.HttpStatus来配置
- methods: 需要重试的请求方法,需要根据枚举org.springframework.http.HttpMethod来配置
- series: HTTP状态码系列,详情见枚举org.springframework.http.HttpStatus.Series
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
上面例子,当下游服务返回502状态码时,gateway会重试3次
22)RequestSize
RequestSize GatewayFilter Factory会限制客户端请求包的大小,通过参数
RequestSize
来配置最大上传大小,单位字节
spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000
如果请求大小超过5000kb限制,则会返回状态码
413 Payload Too Large
如果不设置这个filter,默认限制5M的请求大小。
23)ModifyRequestBody
官方说这个filter目前只是beta版本,API以后可能会修改
Modify Request Body GatewayFilter Factory可以修改请求体内容,这个只能通过java来配置
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
(exchange, s) -> return Mono.just(new Hello(s.toUpperCase())))).uri(uri))
.build();
}
static class Hello {
String message;
public Hello() { }
public Hello(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
24)ModifyResponseBody
官方说这个filter目前只是beta版本,API以后可能会修改
Modify Response Body GatewayFilter Factory用于修改响应返回的内容,同样只能通过java配置
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyResponseBody(String.class, String.class,
(exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri)
.build();
}