在以前的文章的Spring Cloud Gateway初体验中,你们已经对Spring Cloud Gateway的功能有一个初步的认识,网关做为一个系统的流量的入口,有着举足轻重的做用,一般的做用以下:前端
Spring Cloud Gateway做为Spring Cloud框架的第二代网关,在功能上要比Zuul更加的强大,性能也更好。随着Spring Cloud的版本迭代,Spring Cloud官方有打算弃用Zuul的意思。在笔者调用了Spring Cloud Gateway的使用和功能上,Spring Cloud Gateway替换掉Zuul的成本上是很是低的,几乎能够无缝切换。Spring Cloud Gateway几乎包含了zuul的全部功能。git
如上图所示,客户端向Spring Cloud Gateway发出请求。 若是Gateway Handler Mapping肯定请求与路由匹配(这个时候就用到predicate),则将其发送到Gateway web handler处理。 Gateway web handler处理请求时会通过一系列的过滤器链。 过滤器链被虚线划分的缘由是过滤器链能够在发送代理请求以前或以后执行过滤逻辑。 先执行全部“pre”过滤器逻辑,而后进行代理请求。 在发出代理请求以后,收到代理服务的响应以后执行“post”过滤器逻辑。这跟zuul的处理过程很相似。在执行全部“pre”过滤器逻辑时,每每进行了鉴权、限流、日志输出等功能,以及请求头的更改、协议的转换;转发以后收到响应以后,会执行全部“post”过滤器的逻辑,在这里能够响应数据进行了修改,好比响应头、协议的转换等。程序员
在上面的处理过程当中,有一个重要的点就是讲请求和路由进行匹配,这时候就须要用到predicate,它是决定了一个请求走哪个路由。github
Predicate 来源于 Java 8,是 Java 8 中引入的一个函数,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其余复杂的逻辑(好比:与,或,非)。能够用于接口请求参数校验、判断新老数据是否有变化须要进行更新操做。web
在 Spring Cloud Gateway 中 Spring 利用 Predicate 的特性实现了各类路由匹配规则,有经过 Header、请求参数等不一样的条件来进行做为条件匹配到对应的路由。网上有一张图总结了 Spring Cloud 内置的几种 Predicate 的实现。正则表达式
说白了 Predicate 就是为了实现一组匹配规则,方便让请求过来找到对应的 Route 进行处理,接下来咱们接下 Spring Cloud GateWay 内置几种 Predicate 的使用。spring
Predicate 支持设置一个时间,在请求进行转发的时候,能够经过判断在这个时间以前或者以后进行转发。好比咱们如今设置只有在2019年2月15日才会转发到个人简书地址,在这以前不进行转发,我就能够这样配置:shell
spring: cloud: gateway: routes: - id: after_route uri: http://httpbin.org predicates: - After=2018-02-15T00:00:00+08:00[Asia/Shanghai]
Spring 是经过 ZonedDateTime 来对时间进行的对比,ZonedDateTime 是 Java 8 中日期时间功能里,用于表示带时区的日期与时间信息的类,ZonedDateTime 支持经过时区来设置时间,中国的时区是:Asia/Shanghai。缓存
After Route Predicate 是指在这个时间以后的请求都转发到目标地址。上面的示例是指,请求时间在 2019年2月15日0点0分0秒以后的全部请求都转发到地址http://httpbin.org。+08:00是指时间和UTC时间相差八个小时,时间地区为Asia/Shanghaimarkdown
添加完路由规则以后,访问地址 http://127.0.0.1:8080/get 会自动转发到 http://httpbin.org/get
Before Route Predicate 恰好相反,在某个时间以前的请求的请求都进行转发。咱们把上面路由规则中的 After 改成 Before,以下:
spring: cloud: gateway: routes: - id: before_route uri: http://httpbin.org predicates: - Before=2019-02-15T00:00:00+08:00[Asia/Shanghai]
就表示在2019-02-14以前能够进行路由,在这时间以后中止路由,修改完以后重启项目再次访问地址http://localhost:8080,页面会报 404 没有找到地址。
除过在时间以前或者以后外,Gateway 还支持限制路由请求在某一个时间段范围内,可使用 Between Route Predicate 来实现。
spring: cloud: gateway: routes: - id: between_route uri: http://httpbin.org predicates: - Between=2018-02-14T00:00:00+08:00[Asia/Shanghai], 2019-02-16T23:59:59+08:00[Asia/Shanghai]
这样设置就意味着在 2019-02-14到2019-02-16 时间段内能够匹配到此路由,超过这个时间段范围则不会进行匹配。经过时间匹配路由的功能很酷,能够用在限时抢购的一些场景中。
Cookie Route Predicate 能够接收两个参数,一个是 Cookie name ,一个是正则表达式,路由规则会经过获取对应的 Cookie name 值和正则表达式去匹配,若是匹配上就会执行路由,若是没有匹配上则不执行。
spring: cloud: gateway: routes: - id: cookie_route uri: http://httpbin.org:80 predicates: - Cookie=name, chengxuyuanguoguo
上面的配置中,请求带有cookie名为name, cookie值为chengxuyuanguoguo 的请求将都会转发到uri为 http://httpbin.org的地址上。
使用 curl 测试,命令行输入:
curl http://127.0.0.1:8080/get --cookie "name=chengxuyuanguoguo"
则有正确返回,若是去掉--cookie "name=chengxuyuanguoguo",没有匹配成功,出现 404 错误。
Header Route Predicate 和 Cookie Route Predicate 同样,也是接收 2 个参数,一个 header 中属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行。
spring: cloud: gateway: routes: - id: header_route uri: http://httpbin.org predicates: - Header=X-Request-Id, \d+
使用 curl 测试,命令行输入:
curl http://127.0.0.1:8080/get -H "X-Request-Id:111111"
则正常返回,将参数 "X-Request-Id:111111" 改成 "X-Request-Id:xxxx" 再次执行时返回404。
Host Route Predicate 接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号做为分隔符。它经过参数中的主机地址做为匹配规则。
spring: cloud: gateway: routes: - id: host_route uri: http://ityouknow.com predicates: - Host=**.ityouknow.com
使用 curl 测试,命令行输入:
curl http://127.0.0.1:8080/get -H "Host:www.httpbin.com"
测试上述 host 可匹配到 host_route 路由,去掉 host 参数则会报 404 错误。
能够经过是 POST、GET、PUT、DELETE 等不一样的请求方式来进行路由。
spring: cloud: gateway: routes: - id: method_route uri: http://httpbin.org predicates: - Method=GET
使用 curl 测试,命令行输入:
curl http://127.0.0.1:8080/get
测试返回正确,证实匹配到路由,再以 POST 的方式请求测试:
curl -X POST http://127.0.0.1:8080/get
返回 404 没有找到,没有匹配上路由。
Path Route Predicate 接收一个匹配路径的参数来判断是否走路由。
spring: cloud: gateway: routes: - id: path_route uri: http://httpbin.org predicates: - Path=/foo/{segment}
使用 curl 测试,命令行输入:
curl http://127.0.0.1:8080/foo/1 curl http://127.0.0.1:8080/fee/1
测试第一命令能够正常获取到页面返回值,第二个命令报404,证实路由是经过指定路由来匹配。
Query Route Predicate 支持传入两个参数,一个是属性名一个为属性值,属性值能够是正则表达式。
spring: cloud: gateway: routes: - id: query_route uri: http://httpbin.org predicates: - Query=foo
测试发现只要请求带有 foo 参数即会匹配路由,不带 foo 参数则会报 404 错误。
Predicate 也支持经过设置某个 ip 区间号段的请求才会路由,RemoteAddr Route Predicate 接受 cidr 符号(IPv4 或 IPv6 )字符串的列表(最小大小 1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子网掩码)。
spring: cloud: gateway: routes: - id: remoteaddr_route uri: http://httpbin.org predicates: - RemoteAddr=172.16.1.73/24
使用 curl 测试,命令行输入:
curl http://172.17.1.73:8080/get
测试返回正确,改成请求 127.0.0.1:8080/get 则会报 404 错误。
Predicate还能够组合在一块儿使用。
spring: cloud: gateway: routes: - id: group_route uri: http://httpbin.org predicates: - Host=**.httpbin.com - Header=X-Request-Id, \d+ - Cookie=name, chengxuyuanguoguo - After=2019-02-15T00:00:00+08:00[Asia/Shanghai]
使用 curl 测试,命令行输入:
curl http://127.0.0.1:8080 -H "X-Request-Id:111111" -H "Host:www.httpbin.com" --cookie "name=chengxuyuanguoguo"
测试返回正确,错误的规则或去除一个规则,则会报 404 错误。
Predict做为断言,它决定了请求会被路由到哪一个router 中。在断言以后,请求会被进入到filter过滤器的逻辑,下篇文章将会介绍Spring Cloud Gateway过滤器相关的内容。
源码:https://github.com/gf-huanchupk/SpringCloudLearning/tree/master/chapter13/springcloud-gateway-predict
欢迎关注个人公众号《程序员果果》,关注有惊喜~~