Spring Cloud gateway文档阅读
This commit is contained in:
@@ -87,4 +87,359 @@ spring:
|
|||||||
```
|
```
|
||||||
上述cookie_route会匹配请求中含有name为chocolate的cookie,并且cookie值满足`ch.p`正则表达式的请求。
|
上述cookie_route会匹配请求中含有name为chocolate的cookie,并且cookie值满足`ch.p`正则表达式的请求。
|
||||||
### Header Route Predicate Factory
|
### Header Route Predicate Factory
|
||||||
Header Route Predicate Factory接收两个参数,`header`和`regexp`。
|
Header Route Predicate Factory接收两个参数,`header`和`regexp`(regexp是正则表达式)。该predicate会匹配一个拥有指定名称header的请求,且header对应的值要满足regexp表达式。
|
||||||
|
如下示例显示了header route predicate的用法:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: header_route
|
||||||
|
uri: https://example.org
|
||||||
|
predicates:
|
||||||
|
- Header=X-Request-Id, \d+
|
||||||
|
```
|
||||||
|
### Host Route Predicate Factory
|
||||||
|
Host Route Predicate Factory接收一个参数:一个pattern列表。pattern是ant-style并用`.`作为分隔符。该predicate会匹配`Host`header,示例如下所示:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: host_route
|
||||||
|
uri: https://example.org
|
||||||
|
predicates:
|
||||||
|
- Host=**.somehost.org,**.anotherhost.org
|
||||||
|
```
|
||||||
|
URI template 变量例如`{sub}.myhost.org`也支持。
|
||||||
|
该route会匹配如下请求:headers中包含name为Host的header,并且Host header的值为`www.somehost.org`,`beta.somehost.org`,`www.anotherhost.org`等形式
|
||||||
|
### Method Route Predicate Factory
|
||||||
|
Method Route Predicate Factory接收一个`methods`参数,其指定了匹配的HTTP METHOD. 如下示例指定了一个method route predicate示例:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: method_route
|
||||||
|
uri: https://example.org
|
||||||
|
predicates:
|
||||||
|
- Method=GET,POST
|
||||||
|
```
|
||||||
|
该predicate匹配method为GET或POST的任意请求。
|
||||||
|
### Path Route Predicate Factory
|
||||||
|
Path Route Predicate Factory接收两个参数,一个PathMatcher Pattern的列表,和一个可选的matchTrailingSlash(默认设置为true)。
|
||||||
|
如下实例配置了一条path route predicate:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: path_route
|
||||||
|
uri: https://example.org
|
||||||
|
predicates:
|
||||||
|
- Path=/red/{segment},/blue/{segment}
|
||||||
|
```
|
||||||
|
上述配置的route能够匹配/red/1或/red/1/、/red/blue或/blue/green.
|
||||||
|
如果`matchTrailingSlash`被设置为false,那么/red/1/将不会被匹配到。
|
||||||
|
该predicate将URI template变量(例如segment)解析为name、value键值对并且放到ServerWebExchange.getAttributes()中。这些值可以被GatewayFilter factories使用。
|
||||||
|
可以通过如下的工具类方法来对这些变量进行访问,按如下示例所示:
|
||||||
|
```java
|
||||||
|
Map<String, String> uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange);
|
||||||
|
|
||||||
|
String segment = uriVariables.get("segment");
|
||||||
|
```
|
||||||
|
### Query Route Predicate Factory
|
||||||
|
Query Route Predicate Factory接收两个参数:必填参数param和可选参数regexp,示例如下所示:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: query_route
|
||||||
|
uri: https://example.org
|
||||||
|
predicates:
|
||||||
|
- Query=green
|
||||||
|
```
|
||||||
|
上述路由配置,匹配请求参数中含有green参数的请求
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: query_route
|
||||||
|
uri: https://example.org
|
||||||
|
predicates:
|
||||||
|
- Query=red, gree.
|
||||||
|
```
|
||||||
|
该route则是匹配请求参数含有red,并且其value满足`gree.`正则表达式的请求。
|
||||||
|
### RemoteAddr Route Predicate Factory
|
||||||
|
RemoteAddr route predicate factory接收一个`sources`列表(列表最小长度为1),列表元素为ipv4或ipv6字符串,例如`192.168.0.1/1`.
|
||||||
|
如下显示了一个RemoteAddr route predicate示例:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: remoteaddr_route
|
||||||
|
uri: https://example.org
|
||||||
|
predicates:
|
||||||
|
- RemoteAddr=192.168.1.1/24
|
||||||
|
```
|
||||||
|
该route匹配如下请求:如果请求的remote addr满足表达式,例如`192.168.1.10`。
|
||||||
|
#### 修改Remote Addr的解析方式
|
||||||
|
默认情况下,RemoteAddr predicate factory的解析方式是使用请求的remote address。但是,如果Spring Cloud Gateway如果位于proxy layer之后,那么remote address匹配的不是实际的client ip。
|
||||||
|
可以通过自定义`RemoteAddressResolver`来自定义remote address的解析方式。Spring Cloud Gateway附带了一个非默认的remote address reslover,该reslover基于` X-Forwarded-For`header进行解析,该resolver是`XForwardedRemoteAddressResolver`。
|
||||||
|
XForwardedRemoteAddressResolver有两个静态的构造器方法,分别使用了两种不同的安全方式:
|
||||||
|
- `XForwardedRemoteAddressResolver::trustAll`:返回一个RemoteAddressResolver,会一直从`X-Forwarded-For`中取第一个ip address。该方法很容易收到欺骗,因为恶意客户端程序会设置`X-Forwarded-For`字段的初始值,而此时reslover会接收虚假设置的值。
|
||||||
|
- `XForwardedRemoteAddressResolver::maxTrustedIndex`:接收一个index,该index和Spring Cloud Gateway之前运行的受信任设施的数量相关。
|
||||||
|
|
||||||
|
如存在如下header:
|
||||||
|
```yml
|
||||||
|
X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3
|
||||||
|
```
|
||||||
|
如下maxTrustedIndex会产生的remote address将如下所示:
|
||||||
|
| maxTrustedIndex | result |
|
||||||
|
| :-: | :-: |
|
||||||
|
| [Integer.MIN_VALUE,0] | 该范围输入不合法 |
|
||||||
|
| 1 | 0.0.0.3 |
|
||||||
|
| 2 | 0.0.0.2 |
|
||||||
|
| 3 | 0.0.0.1 |
|
||||||
|
| [4, Integer.MAX_VALUE] | 0.0.0.1 |
|
||||||
|
|
||||||
|
如下展示了如何通过java代码来完成相同的配置:
|
||||||
|
```java
|
||||||
|
RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
|
||||||
|
.maxTrustedIndex(1);
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
.route("direct-route",
|
||||||
|
r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
|
||||||
|
.uri("https://downstream1")
|
||||||
|
.route("proxied-route",
|
||||||
|
r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24")
|
||||||
|
.uri("https://downstream2")
|
||||||
|
)
|
||||||
|
```
|
||||||
|
### Weight Route Predicate Factory
|
||||||
|
Weight Route Predicate Factory接收两个参数:`group`和`weight`,weight将对每个group进行计算。如下示例配置了一个Weight Route Predicate:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: weight_high
|
||||||
|
uri: https://weighthigh.org
|
||||||
|
predicates:
|
||||||
|
- Weight=group1, 8
|
||||||
|
- id: weight_low
|
||||||
|
uri: https://weightlow.org
|
||||||
|
predicates:
|
||||||
|
- Weight=group1, 2
|
||||||
|
```
|
||||||
|
该route将会把80%的负载转发到https://weighthigh.org,把20%的负载发送到https://weightlow.org
|
||||||
|
### XForwarded Remote Addr Route Predicate
|
||||||
|
XForwarded Remote Addr Route Predicate接收一个`sources`列表,列表元素为ipv4或ipv6地址,例如`192.168.0.1/16`。
|
||||||
|
该route predicate允许通过`X-Forwarded-For` header来过滤请求。
|
||||||
|
该predicate可以和反向代理服务器(通常用作负载均衡或web应用防火墙)一起使用,只有当请求来源于这些受信ip地址列表时,请求才会被允许访问。
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: xforwarded_remoteaddr_route
|
||||||
|
uri: https://example.org
|
||||||
|
predicates:
|
||||||
|
- XForwardedRemoteAddr=192.168.1.1/24
|
||||||
|
```
|
||||||
|
上述route,只有当`X-Forwarded-For` header中包含例如`192.168.1.10`的ip时,请求才会被匹配。
|
||||||
|
|
||||||
|
## GatewayFilter Factory
|
||||||
|
Route filters 允许对进入的请求和外出的响应进行修改,Route Filter作用域为特定的route。Spring Cloud Gateway有许多内置的route filter。
|
||||||
|
### AddRequestHeader GatewayFilter Factory
|
||||||
|
AddRequestHeader GatewayFilter Factory接收一个name和value参数,如下示例配置了一个AddRequestHeader GatewayFilter:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: add_request_header_route
|
||||||
|
uri: https://example.org
|
||||||
|
filters:
|
||||||
|
- AddRequestHeader=X-Request-red, blue
|
||||||
|
```
|
||||||
|
上述配置对所有匹配的请求在下游请求头中添加了`X-Request-red:blue`header。
|
||||||
|
AddRequestHeader可以使用用于匹配path或host的URI变量。URI变量可以在value中使用,并且在运行时自动拓展,如下示例配置了一个使用URI变量的`AddRequestHeader GatewayFilter`:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: add_request_header_route
|
||||||
|
uri: https://example.org
|
||||||
|
predicates:
|
||||||
|
- Path=/red/{segment}
|
||||||
|
filters:
|
||||||
|
- AddRequestHeader=X-Request-Red, Blue-{segment}
|
||||||
|
```
|
||||||
|
### AddRequestHeadersIfNotPresent GatewayFilter Factory
|
||||||
|
AddRequestHeadersIfNotPresent GatewayFilter接收一个name和value对集合,name和value之间通过`:`进行分隔,如下示例配置了一个filter:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: add_request_headers_route
|
||||||
|
uri: https://example.org
|
||||||
|
filters:
|
||||||
|
- AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-2:green
|
||||||
|
```
|
||||||
|
上述配置会添加两个headers`X-Request-Color-1:blue`和`X-Request-Color-2:green`到下游请求的headers中。该操作和`AddRequestHeader`类似,但是AddRequestHeadersIfNotPresent只会当header不存在时才进行添加。如果该header存在,那么会保留该header的原有值。
|
||||||
|
> 如果要设置一个multi-valued header,可以使用该headerName多次,例如`AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-1:green`
|
||||||
|
|
||||||
|
`AddRequestHeadersIfNotPresent`也支持URI变量,如下配置了一个使用URI变量的Gateway Filter:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: add_request_header_route
|
||||||
|
uri: https://example.org
|
||||||
|
predicates:
|
||||||
|
- Path=/red/{segment}
|
||||||
|
filters:
|
||||||
|
- AddRequestHeadersIfNotPresent=X-Request-Red:Blue-{segment}
|
||||||
|
```
|
||||||
|
### AddRequestParameter GatewayFilter Factory
|
||||||
|
AddRequestParameter GatewayFilter Factory接收一个name和value参数,如下示例配置了一个filter:
|
||||||
|
```xml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: add_request_parameter_route
|
||||||
|
uri: https://example.org
|
||||||
|
filters:
|
||||||
|
- AddRequestParameter=red, blue
|
||||||
|
```
|
||||||
|
上述配置会向下游请求中加入请求参数。
|
||||||
|
AddRequestParameter GatewayFilter可以使用URI变量,使用URI变量的配置如下所示:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: add_request_parameter_route
|
||||||
|
uri: https://example.org
|
||||||
|
predicates:
|
||||||
|
- Host: {segment}.myhost.org
|
||||||
|
filters:
|
||||||
|
- AddRequestParameter=foo, bar-{segment}
|
||||||
|
```
|
||||||
|
### AddResponseHeader GatewayFilter Factory
|
||||||
|
`AddResponseHeader GatewayFilter Factory接收一个name和value参数,如下配置了一个filter:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: add_response_header_route
|
||||||
|
uri: https://example.org
|
||||||
|
filters:
|
||||||
|
- AddResponseHeader=X-Response-Red, Blue
|
||||||
|
```
|
||||||
|
该filter添加了`X-Response-Red:Blue` header到下游响应的headers中。
|
||||||
|
`AddResponseHeader GatewayFilter`可以使用URI变量,如下实例展示了使用URI变量的配置:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: add_response_header_route
|
||||||
|
uri: https://example.org
|
||||||
|
predicates:
|
||||||
|
- Host: {segment}.myhost.org
|
||||||
|
filters:
|
||||||
|
- AddResponseHeader=foo, bar-{segment}
|
||||||
|
```
|
||||||
|
### CircuitBreaker GatewayFilter Factory
|
||||||
|
CircuitBreaker GatewayFilter Factory使用了Spring Cloud CircuitBreaker API来将网关路由包装到断路器中。
|
||||||
|
为了启用Spring Cloud CircuitBreaker filter,需要将`spring-cloud-starter-circuitbreaker-reactor-resilience4j`放到classpath路径下,如下示例配置了filter:
|
||||||
|
```xml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: circuitbreaker_route
|
||||||
|
uri: https://example.org
|
||||||
|
filters:
|
||||||
|
- CircuitBreaker=myCircuitBreaker
|
||||||
|
```
|
||||||
|
### CacheRequestBody GatewayFilter Factory
|
||||||
|
有一些场景需要读取请求体,因为请求只能被读取一次,因此需要缓存请求体。可以使用CacheRequestBody filter来缓存请求体,在请求被发送到下游之前,并且可以从`exchange`属性中获取请求体。
|
||||||
|
```xml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: cache_request_body_route
|
||||||
|
uri: lb://downstream
|
||||||
|
predicates:
|
||||||
|
- Path=/downstream/**
|
||||||
|
filters:
|
||||||
|
- name: CacheRequestBody
|
||||||
|
args:
|
||||||
|
bodyClass: java.lang.String
|
||||||
|
```
|
||||||
|
上述配置获取请求体并且将请求体转为了String类型,后续可以通过`ServerWebExchange.getAttributes()`来获取,key为`ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR`.
|
||||||
|
|
||||||
|
### DedupeResponseHeader GatewayFilter Factory
|
||||||
|
DedupeResponseHeader GatewayFilter factory接收一个name参数和一个可选的strategy参数,name是一个用空格分隔的list,list元素为header name。如下配置了一个filter示例:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
routes:
|
||||||
|
- id: dedupe_response_header_route
|
||||||
|
uri: https://example.org
|
||||||
|
filters:
|
||||||
|
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
|
||||||
|
```
|
||||||
|
上述配置中移除了Access-Control-Allow-Credentials和Access-Control-Allow-Origin响应header中的重复值,当gateway cors逻辑和下游逻辑都添加了它们时。
|
||||||
|
DedupeResponseHeader还有一个可选的strategy参数,默认为RETAIN_FIRST,还可以是RETAIN_LAST和RETAIN_UNIQUE。
|
||||||
|
|
||||||
|
### 默认filters
|
||||||
|
如果想要添加一个filter并将其应用到所有的routes中,可以使用`spring.cloud.gateway.default-filters`,该属性可以接收一个filter列表。如下定义了一系列默认filter:
|
||||||
|
```yml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
default-filters:
|
||||||
|
- AddResponseHeader=X-Response-Default-Red, Default-Blue
|
||||||
|
- PrefixPath=/httpbin
|
||||||
|
```
|
||||||
|
## Global Filters
|
||||||
|
GlobalFilter接口的签名和Gateway接口的签名一样。GlobalFilter会在满足条件后应用于所有的routes。
|
||||||
|
### 组合Global Filter和Gateway Filter
|
||||||
|
当请求匹配到一个route之后,filtering web handler将所有的GlobalFilter实例和route对应的Gateway Filter实例添加到一个filter chain中。该filter chain通过`org.springframework.core.Ordered`接口进行排序。filter chain中排序最靠前的filter在pre-phase中位于第一个,并且在post-phase中位于最后一个。
|
||||||
|
如下配置了一个filter chain:
|
||||||
|
```java
|
||||||
|
@Bean
|
||||||
|
public GlobalFilter customFilter() {
|
||||||
|
return new CustomGlobalFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CustomGlobalFilter implements GlobalFilter, Ordered {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
|
log.info("custom global filter");
|
||||||
|
return chain.filter(exchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user