一 何为路由谓词工厂(Route Predicate Factories
)
Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分。 Spring Cloud Gateway包括许多内置的路由谓词工厂。所有这些谓词都与HTTP请求的不同属性匹配。可以将多个路由谓词工厂与逻辑和语句结合使用。
二 框架自带了哪些路由谓词工厂
After
RoutePredicate
FactoryAfterRoutePredicateFactory
接收一个参数,即datetime
(这是一个JavaZonedDateTime
)。该谓词匹配在指定日期时间之后发生的请求。如以下示例配置:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]Before
RoutePredicate
FactoryBeforeRoutePredicateFactory
接收一个参数,即datetime
(这是一个JavaZonedDateTime
)。该谓词匹配在指定日期时间之前发生的请求。如以下示例配置:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]Between
RoutePredicate
FactoryBetweenRoutePredicateFactory
接收两个参数datetime1
和datetime2
,它们是javaZonedDateTime
对象。该谓词匹配在datetime1
之后和datetime2
之前发生的请求。datetime2
参数必须在datetime1
之后。如以下示例配置:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]Cookie
RoutePredicate
FactoryCookieRoutePredicateFactory
接收两个参数,即cookiename
和一个regexp
(这是Java正则表达式)。该谓词匹配具有给定名称且其值与正则表达式匹配的cookie。以下示例配置Cookie路由谓词工厂:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.pHeader
RoutePredicate
FactoryHeaderRoutePredicateFactory
接收两个参数,请求头的name
和一个regexp
(这是Java正则表达式)。该谓词与具有给定名称的请求头匹配,该请求头的值与正则表达式匹配。以下示例配置标头路由谓词:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+Host
RoutePredicate
FactoryHostRoutePredicateFactory
接收一个参数,即主机名列表patterns
,该patterns是带有的Ant样式的模式。作为分隔符。该谓词与匹配模式的Host请求头匹配。以下示例配置主机路由谓词:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org还支持URI模板变量(例如
{sub} .myhost.org
),以上示例如果请求的主机请求头的值为www.somehost.org或beta.somehost.org或www.anotherhost.org,则此路由匹配。他的谓词提取URI模板变量(如上例中定义的sub)作为名称和值的映射,并使用
ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
中定义的键将其放置在ServerWebExchange.getAttributes()
中。这些值可供GatewayFilter工厂使用。Method
RoutePredicate
FactoryMethodRoutePredicateFactory
接收methods
参数,该参数是一个或多个参数:要匹配的HTTP方法。以下示例配置方法route谓词:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST此示例,如果请求方法是GET或POST,则此路由匹配。
Path
RoutePredicate
FactoryPathRoutePredicateFactory
是路径路由谓词工厂,在实际生产中是用的最多的,接收两个参数:SpringPathMatcher
patterns
列表和一个称为matchOptionalTrailingSeparator
的可选标志。以下示例配置路径路由谓词:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}该谓词提取URI模板变量(如上例中定义的
segment
)作为名称和值的映射,并使用ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
中定义的键将其放置在ServerWebExchange.getAttributes()
中。这些值可供GatewayFilter工厂使用。访问该变量的方式如下1
2Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("segment");Query
RoutePredicate
FactoryQueryRoutePredicateFactory
是根据查询参数匹配的路由谓词工厂,接收两个参数:必需的param
和可选的regexp
(这是Java正则表达式)。以下示例配置查询路由谓词:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green如果请求包含
green
查询参数,则前面的路由匹配。1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.如上示例,如果查询参数包含
red
,并且其值与gree.
正则匹配,如green
和greet
都会被匹配。RemoteAddr
RoutePredicate
FactoryRemoteAddrRoutePredicateFactory
接收一个参数sources
列表(最小大小为1),这些sources
是CIDR标记(IPv4或IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是IP地址,而16是子网掩码) )。下面的示例配置RemoteAddr路由谓词:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24如果请求的远程地址是例如192.168.1.10,则此路由匹配。
Weight
RoutePredicate
FactoryWeightRoutePredicateFactory
是权重路由谓词工厂,接收两个参数:group
和weight
(一个int)。权重是按组计算的。以下示例配置权重路由谓词:1
2
3
4
5
6
7
8
9
10
11
12spring:
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这条路由会将约80%的流量转发至weighthigh.org,并将约20%的流量转发至weightlow.org。
默认情况下,RemoteAddr路由谓词工厂使用传入请求中的远程地址。如果Spring Cloud Gateway位于代理层后面,则此地址可能与实际的客户端IP地址不匹配。
您可以通过设置自定义的
RemoteAddressResolver
来自定义解析远程地址的方式。 Spring Cloud Gateway随附了一个基于X-Forwarded-For
标头XForwardedRemoteAddressResolver
的非默认远程地址解析器。XForwardedRemoteAddressResolver
有两个静态构造函数方法,它们采用不同的安全性方法:XForwardedRemoteAddressResolver::trustAll
返回一个RemoteAddressResolver
,该地址始终采用X-Forwarded-For
请求头中找到的第一个IP地址。这种方法容易受到欺骗的攻击,因为恶意客户端可能会为X-Forwarded-For
设置初始值,该初始值将被解析器接受。XForwardedRemoteAddressResolver::maxTrustedIndex
获取一个索引,该索引与在Spring Cloud Gateway前面运行的受信任基础结构的数量相关。例如,如果只能通过HAProxy访问Spring Cloud Gateway,则应使用值1。如果在访问Spring Cloud Gateway之前需要两跳可信基础架构,则应使用值2。
Forwarded了多次的,如以下请求头,和
maxTrustedIndex
对应关系1
2> X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3
>
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 |
三 自定义路由谓词工厂
路由谓词工厂的定义与路由过滤器的定义非常相似,我们只需要继承
AbstractRoutePredicateFactory<Config>
,并重写里面的方法apply
方法即可。apply方法重写如下:
1 |
|
定义快捷方式配置写法的字段顺序,重写以下方法:
1 |
|
其中的
Config
一般是自定义过滤器工厂的静态内部类,主要是定义传递的参数,如
1 | public static class Config { |
一个示例如下:
1 | public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> { |