- 介绍
- 1.The After Route Predicate Factory
- 2.The Before Route Predicate Factory
- 3.The Between Route Predicate Factory
- 4.The Cookie Route Predicate Factory
- 5.The Header Route Predicate Factory
- 6.The Host Route Predicate Factory
- 7.The Method Route Predicate Factory
- 8.The Path Route Predicate Factory
- 9.The Query Route Predicate Factory
- 10.The RemoteAddr Route Predicate Factory
- 11.The Weight Route Predicate Factory
启动cloud-gateway-gateway9527项目控制台会打印出入如下内容,说明有如下几种断言规则
介绍
Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分。
Spring Cloud Gateway包括许多内置的Route Predicate工厂。所有这些Predicate都与HTTP请求的不同属性匹配。多个Route Predicate工厂可以进行组合
Spring Cloud Gateway创建 Route 对象时,使用 RoutePredicateFactor 创建 Predicate 对象,Predicate对象可以赋值给Route。Spring Cloud Gateway 包含许多内置的Route Predicate Factories
所有这些谓词都匹配HTTP请求的不同属性。多种谓词工厂可以组合,并通过逻辑and。
1.The After Route Predicate Factory
After路由 predicate 工厂接受一个参数,一个datetime(它是一个java ZonedDateTime)。此 predicate 匹配在指定日期时间之后发生的请求。下面的示例配置一个after路由predicate:
例1。application.yml
spring:
cloud:
gateway:
routes:
- id: after_route
uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
这条路由与丹佛时间2017年1月20日17点42分以后的任何请求相匹配。
以上是日期格式是国外的时区,可以用以下代码获取本地时区
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println(zonedDateTime);
// 输出:2020-04-30T15:48:20.500+08:00[Asia/Shanghai]
2.The Before Route Predicate Factory
Before路由 predicate 工厂接受一个参数,一个datetime(它是一个java ZonedDateTime)。此 predicate 匹配在指定日期时间之前发生的请求。下面的示例配置一个before路由 predicate:
例2. application.ym
spring:
cloud:
gateway:
routes:
- id: before_route
uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
这条路由与丹佛时间2017年1月20日17点42分之前的任何请求相匹配。
3.The Between Route Predicate Factory
route predicate工厂接受两个参数,datetime1和datetime2,它们是java ZonedDateTime对象。此predicate匹配在datetime1之后和datetime2之前发生的请求。datetime2参数必须位于datetime1之后。下面的示例配置一个路由间predicate:
例3. application.yml
spring:
cloud:
gateway:
routes:
- id: between_route
uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
该路由与2017年1月20日(丹佛)17:42山地时间之后和2017年1月21日(丹佛)17:42山地时间之前的任何请求匹配。这对于维护窗口可能很有用。
4.The Cookie Route Predicate Factory
Cookie route predicate工厂接受两个参数,Cookie名称和regexp(它是一个Java正则表达式)。此predicate匹配具有给定名称且其值与正则表达式匹配的cookie。下面的示例配置一个cookie路由谓词工厂:
例4. application.yml
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
predicates:
- Cookie=chocolate, ch.p
此路由匹配具有一个名为chocolate的cookie的请求,该cookie的值与ch.p正则表达式匹配。
使用cURL工具发送带有cookie为chocolate=ch.p
的请求可以匹配该路由。
curl http://localhost:9527/payment/lb/ --cookie "chocolate=ch.p"
5.The Header Route Predicate Factory
头 route predicate 工厂接受两个参数,头名称和regexp(这是一个Java正则表达式)。此predicate与具有给定名称且其值与正则表达式匹配的头匹配。以下示例配置头route predicate:
例 5. application.yml
spring:
cloud:
gateway:
routes:
- id: header_route
uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
predicates:
- Header=X-Request-Id, \d+
如果请求的头名为X-Request-Id,其值与\d+正则表达式匹配(即,它的值为一个或多个数字),则此路由将进行匹配。
使用cURL发送带有请求头为X-Request-Id:123
的请求可以匹配该路由。
curl http://localhost:9527/payment/lb/ -H "X-Request-Id:123"
6.The Host Route Predicate Factory
Host route predicate工厂需要一个参数:主机名的列表 patterns .的模式是一个Ant-style的模式,.
作为分隔符。此 predicate 与模式匹配的主机标头匹配。下面的示例配置一个Host route predicate:
例6. application.yml
spring:
cloud:
gateway:
routes:
- id: host_route
uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
predicates:
- Host=**.somehost.org,**.anotherhost.org
还支持URI模板变量(例如 {sub}.myhost.org)。
如果请求的主机头的值为www.somehost.org或beta.somehost.org或www.anotherhost.org,则此路由匹配。
此predicate将URI模板变量(如前面示例中定义的sub)提取为名称和值的映射,并将其放在ServerWebExchange.getAttributes()中,并在ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE中定义了一个键。然后这些值可供GatewayFilter
factories使用
使用cURL访问带有请求头为www.somehost.org或者www.anotherhost.org的请求可以匹配该路由。
curl http://localhost:9527/payment/lb/ -H "Host:www.somehost.org"
7.The Method Route Predicate Factory
Method
Route Predicate工厂接受一个methods
参数,该参数是一个或多个参数:要匹配的HTTP methods。下面的示例配置一个方法route predicate:
例7. application.yml
spring:
cloud:
gateway:
routes:
- id: method_route
uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
predicates:
- Method=GET,POST
如果请求方法是GET或POST,则此路由匹配。
使用cURL发送GET或POST请求可以匹配该路由。
curl http://localhost:9527/payment/lb/
8.The Path Route Predicate Factory
Path
Route Predicate工厂接受两个参数:一个Spring PathMatcher
patterns
和一个名为matchOptionalTrailingSeparator的可选标志。下面的示例配置一个path route predicate:
例8. application.yml
spring:
cloud:
gateway:
routes:
- id: path_route
uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
predicates:
- Path=/red/{segment},/blue/{segment}
如果请求路径为,例如:/red/1 或/red/blue
或 /blue/green
,则此路由匹配。
该predicate将URI模板变量(如前面示例中定义的segment)提取为名称和值的映射,并将其放入ServerWebExchange.getAttributes()中,并在ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
.中定义了一个键。然后这些值可供GatewayFilter
factories使用
有一个实用方法(称为get)可以使访问这些变量变得更容易。下面的示例演示如何使用get方法:
Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("segment");
9.The Query Route Predicate Factory
Query
route predicate工厂接受两个参数:一个必需的param
和一个可选的regexp
(它是一个Java正则表达式)。下面的示例配置一个查询路由谓词:
例9. application.yml
spring:
cloud:
gateway:
routes:
- id: query_route
uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
predicates:
- Query=green
如果请求包含green
查询参数,则前面的路由匹配。
application.yml
spring:
cloud:
gateway:
routes:
- id: query_route
uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
predicates:
- Query=red, gree.
如果请求包含一个red
查询参数,其值与gree.
匹配,则前面的路由将匹配。regexp,所以green和greet
是匹配的。
使用curl发送带Query=red
查询参数的请求可以匹配该路由。
curl http://localhost:9527/payment/lb/?red=greet
10.The RemoteAddr Route Predicate Factory
RemoteAddr
route predicate 工厂接受 sources 列表(最小大小为1),这些源是CIDR符号(IPv4或IPv6)字符串,比如192.168.0.1/16(其中192.168.0.1是一个IP地址,16
是子网掩码)。下面的示例配置一个RemoteAddr route predicate:
例10. application.yml
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
predicates:
- RemoteAddr=192.168.1.1/24
如果请求的远程地址是192.168.1.10
,则此路由匹配。
11.The Weight Route Predicate Factory
权重 route predicate工厂接受两个参数:组和权值(一个int)。每组计算权重。下面的示例配置一个权重route predicate:
例11. application.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%的流量转发到weigh.org, 20%的流量转发到weighlow.org
11.1.修改远程地址解析的方式
默认情况下,RemoteAddr route predicate工厂使用来自传入请求的远程地址。如果Spring Cloud Gateway位于代理层的后面,这可能与实际的客户端IP地址不匹配。
您可以通过设置自定义RemoteAddressResolver来自定义远程地址的解析方式。Spring Cloud Gateway提供了一个非默认的远程地址解析器,它基于X-Forwarded-For header,XForwardedRemoteAddressResolver。
XForwardedRemoteAddressResolver
有两个静态构造函数方法,它们采用不同的安全方法:
- XForwardedRemoteAddressResolver::trustAll 返回一个RemoteAddressResolver,它总是接受X-Forwarded-For头中找到的第一个IP地址。这种方法容易受到欺骗,因为恶意客户机可以为X-Forwarded-For设置一个初始值,解析器将接受这个初始值。
- XForwardedRemoteAddressResolver::maxTrustedIndex 获取与运行在Spring Cloud Gateway前的可信基础设施数量相关的索引。例如,如果Spring Cloud Gateway只能通过HAProxy访问,那么应该使用值1。如果在访问Spring Cloud Gateway之前需要两个可信基础设施的跃点,那么应该使用值2。
考虑以下头值:
X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3
下列maxTrustedIndex
值产生以下远程地址:
maxTrustedIndex | result |
---|---|
[Integer.MIN_VALUE ,0] |
(invalid, IllegalArgumentException during initialization) |
1 | 0.0.0.3 |
2 | 0.0.0.2 |
3 | 0.0.0.1 |
[4, Integer.MAX_VALUE ] |
0.0.0.1 |
下面的例子展示了如何用Java实现相同的配置:
例12. GatewayConfig.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")
)