一、断言(Predicate)的意义
断言是路由配置的一部分,当断言条件满足,即执行Filter的逻辑,如下例所示
spring:cloud:gateway:routes:- id: add_request_header_routeuri: https://example.orgpredicates:- Path=/red/{segment}filters:- AddRequestHeader=X-Request-Red, Blue-{segment}
当请求路径满足条件/red/,即添加头信息:X-Request-Red,value为Blue-{segment},segment是路径里面带的信息。
gateWay的主要功能之一是转发请求,转发规则的定义主要包含三个部分
Route(路由) | 路由是网关的基本单元,由ID、URI、一组Predicate、一组Filter组成,根据Predicate进行匹配转发。 |
Predicate(谓语、断言) | 路由转发的判断条件,目前SpringCloud Gateway支持多种方式,常见如:Path、Query、Method、Header等,写法必须遵循 key=vlue的形式 |
Filter(过滤器) | 过滤器是路由转发请求时所经过的过滤逻辑,可用于修改请求、响应内容 |
其中Route和Predicate必须同时申明
以下内容,来自于SpringCloud Gateway官网,经过整理得来。
二、配置路由断言
注意:以下的配置,只写了routes配置的predicates的部分,实际上,predicates单独用没有意义,一般要配置filter来用。如上面的添加头信息的示例。
1.1 简写配置
由过滤器名称,后跟等号,后跟逗号分割的参数值
spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- Cookie=mycookie,mycookievalue
1.2 展开的写法
spring:cloud:gateway:routes:- id: test_cookieuri: https://example.orgpredicates:- name: Cookieargs:name: mycookieregexp: mycookievalue
以上两个写法,效果是一样的。
问题1:展开的predicates的展开写法为什么是这么写?
原因是,这个配置对应的配置类是这么写的
问题2:name:Cookie是怎么来的?
根据类名来的,CookieRoutePredicateFactory,取的Cookie前缀,还有很多断言工厂,如下:
问题3:为啥args下面是name和regexp?
三、路由断言工厂示例
Spring Cloud Gateway 路由匹配作为Spring WebFlux HandlerMapping 基础设施的一部分。Spring Cloud Gateway内置了很多路由断言工厂。用于匹配HTTP请求的不同属性。
注意:以下的配置,只写了routes配置的predicates的部分,实际上,predicates单独用没有意义,一般要配置filter来用。如上面的添加头信息的示例。
2.1 The After Route Predicate Factory
spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After=2017-01-20T17:42:47.789-07:00[America/Denver]
匹配2017-01-20T17:42:47.789-07:00之后的请求
2.2 The Before Route Predicate Factory
spring:cloud:gateway:routes:- id: before_routeuri: https://example.orgpredicates:- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
匹配2017-01-20T17:42:47.789-07:00之前的请求
2.3 The Between Route Predicate Factory
spring:cloud:gateway:routes:- id: between_routeuri: https://example.orgpredicates:- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
表示在第一个时间之后,第二个时间之前的请求才能正确匹配路由
2.4 The Cookie Route Predicate Factory
spring:cloud:gateway:routes:- id: cookie_routeuri: https://example.orgpredicates:- Cookie=chocolate, ch.p
接收两个参数,分别为name 和 regexp(Java正则表达式),表示cookie中携带的name值满足正则表达式regexp,则被路由
2.5 The Header Route Predicate Factory
spring:cloud:gateway:routes:- id: header_routeuri: https://example.orgpredicates:- Header=X-Request-Id, \d+
接收两个参数,header 和 regexp(Java正则表达式),表示header中携带的name值满足正则表达式regexp,则被路由
2.6 The Host Route Predicate Factory
spring:cloud:gateway:routes:- id: host_routeuri: https://example.orgpredicates:- Host=**.somehost.org,**.anotherhost.org
支持URI模板变量(如{sub}.myhost.org)。当Host 头的值为 www.somehost.org 或 beta.somehost.org 或 www.anotherhost.org 都能匹配该路由。
Predicate 会提取URI模板变量作为map集合,并放置在 ServerWebExchange.getAttributes() 中,key定义为 ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE ,这些值能在 GatewayFilter工厂中使用。
2.7 The Method Route Predicate Factory
spring:cloud:gateway:routes:- id: method_routeuri: https://example.orgpredicates:- Method=GET,POST
上面示例表示匹配 GET ,POST请求
2.8 The Path Route Predicate Factory
spring:cloud:gateway:routes:- id: path_routeuri: https://example.orgpredicates:- Path=/red/{segment},/blue/{segment}
如果请求地址是 /red/1 或 /red/1/ 或 /red/blue 或 /blue/green ,那么路由将会被匹配。
如果 matchTrailingSlash 设置为 false ,那么 /red/1/ 不会被匹配。
Predicate 会提取URI模板变量作为map集合,并放置在 ServerWebExchange.getAttributes() 中,key定义
为 ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE ,这些值能在 GatewayFilter 工厂中使用。
可以使用个实用法(调用get)来简化对这些变量的访问。下面的例示展示了如何使用get方法:
Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);String segment = uriVariables.get("segment");
2.9 The Query Route Predicate Factory
spring:cloud:gateway:routes:- id: query_routeuri: https://example.orgpredicates:- Query=green
接收两个参数,分别是一个必须的param和一个可选的regexp。
spring:cloud:gateway:routes:- id: query_routeuri: https://example.orgpredicates:- Query=red, gree.
red和gree两个参数都有才满足
2.10 The RemoteAddr Route Predicate Factory
spring:cloud:gateway:routes:- id: remoteaddr_routeuri: https://example.orgpredicates:- RemoteAddr=192.168.1.1/24.
接收⼀个sources列表(最小1个),CIDR表示法(IPv4或IPv6)字符串,例如192.168.0.1/16(其中192.168.0.1是
⼀个IP地址,16是⼀个⼦网掩码)。
如果请求的远程地址是 192.168.1.10 ,则此路由被匹配
2.11 The Weight Route Predicate Factory
spring:cloud:gateway:routes:- id: weight_highuri: https://weighthigh.orgpredicates:- Weight=group1, 8- id: weight_lowuri: https://weightlow.orgpredicates:- Weight=group1, 2
将有80%的流量被路由到 weighthigh.org ,20%的流量被路由到 weightlow.org 。