0
点赞
收藏
分享

微信扫一扫

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用


文章目录

  • ​​一、前言​​
  • ​​二、PredicateFactory(Route Predicate Factories)​​
  • ​​1、时间相关​​
  • ​​1)AfterRoutePredicateFactory​​
  • ​​1> 匹配谓语时​​
  • ​​2> 不匹配谓语时​​
  • ​​2)BeforeRoutePredicateFactory​​
  • ​​3)BetweenRoutePredicateFactory​​
  • ​​2、Cookie相关(CookieRoutePredicateFactory)​​
  • ​​3、Header相关(HeaderRoutePredicateFactory)​​
  • ​​4、Host相关(HostRoutePredicateFactory)​​
  • ​​5、Method相关(MethodRoutePredicateFactory)​​
  • ​​6、Path相关(PathRoutePredicateFactory)​​
  • ​​StripePrefix Filter​​
  • ​​7、Query相关(QueryRoutePredicateFactory)​​
  • ​​1)仅匹配查询属性名​​
  • ​​2)匹配查询属性名和属性名对应的值​​
  • ​​8、请求IP地址相关(RemoteAddrRoutePredicateFactory)​​
  • ​​9、负载权重相关(WeightRoutePredicateFactory)​​
  • ​​10、组合使用​​
  • ​​三、总结和后续​​

一、前言

至此微服务网关系列文章已出:

  1. ​​【云原生&微服务>SCG网关篇一】为什么要有网关、生产环境如何选择网关​​
  2. ​​云原生&微服务>SCG网关篇二】生产上那些灰度发布方式​​
  3. ​​【云原生&微服务>SCG网关篇三】Spring Cloud Gateway是什么、详细使用案例​​

聊了以下问题:

  1. 为什么要有网关?网关的作用是什么?
  2. 网关的分类?
  3. 网关的技术选型?
  4. 使用网关时常用的灰度发布方式有哪些?
  5. Spring Cloud Gateway是什么?详细使用案例?

本文接着聊SpringCloudGateway内嵌的PredicateFactory如何使用;

PS:SpringCloud版本信息:

<properties>
<spring-boot.version>2.4.2</spring-boot.version>
<spring-cloud.version>2020.0.1</spring-cloud.version>
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--整合spring cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--整合spring cloud alibaba-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

二、PredicateFactory(Route Predicate Factories)

路由谓词工厂(​​Route Predicate Factories​​)负责生成一些谓词条件(匹配规则),让请求过来的时候找到对应的 Route 进行处理,并且谓词工厂可以多个一起使用。

Gateway内置了很多谓词工厂,从​​官方文档​​来看,Spring Cloud Gateway内置了11种PredicateFactory:

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用_微服务

但是我们跟到​​spring-cloud-gateway-server:3.0.1​​项目的源代码中会发现,好像比文档中多了两个(CloudFoundryRouteServiceRoutePredicateFactory、ReadBodyRoutePredicateFactory):

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用_微服务_02

不知道官方是什么用意,我们这里就先不管这多出的两个PredicateFactory;接着看Spring Cloud GateWay 内置的11种 PredicateFactory 的使用。

1、时间相关

Route Predicate Factory支持设置一个时间或一个时间范围,在Gateway请求进行转发的时候,可以通过判断在这个时间之前、之后 或 之间决定如何转发、是否转发;

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用_spring_03

从官方文档我们可以看出在 Spring 中是通过 ​​ZonedDateTime​​ 来对时间进行的对比,ZonedDateTime 是 Java 8 中用于表示带时区的日期时间信息类,ZonedDateTime 支持通过时区来设置时间,中国的时区是:Asia/Shanghai。

1)AfterRoutePredicateFactory

After Route Predicate匹配在指定日期时间之后发生的请求;

1> 匹配谓语时

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: time_before_route
uri: http://127.0.0.1:9001
predicates:
- After=2022-01-01T00:00:00.000+08:00[Asia/Shanghai]

这里表示所有在​​北京时间2022年1月1日 00:00:00​​​之后访问​​http://127.0.0.1:9999​​​地址的请求都会被路由到​​http://127.0.0.1:9001​​地址上;

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用_spring_04

2> 不匹配谓语时

当前时间为北京时间​​2022-07-13 19:00:00​​​,把After Route Predicate的时间改为北京时间​​2022-07-13 21:00:00​​;

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: time_before_route
uri: http://127.0.0.1:9001
predicates:
- After=2022-07-13T13:00:00.000+08:00[Asia/Shanghai]

由于当前时间还没到北京时间​​2022-07-13 21:00:00​​​,所以请求​​http://127.0.0.1:9999​​地址的请求都会报错404,not found。

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用_spring_05

后续本文只给出符合Predicate谓语的情况,不符合的情况以此类推。

2)BeforeRoutePredicateFactory

Before Route Predicate匹配在指定日期时间之前发生的请求;

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: time_after_route
uri: http://127.0.0.1:9001
predicates:
- Before=2023-01-01T00:00:00.000+08:00[Asia/Shanghai]

这里表示所有在​​北京时间2023年1月1日 00:00:00​​​之前访问​​http://127.0.0.1:9999​​​地址的请求都会被路由到​​http://127.0.0.1:9001​​地址上;

3)BetweenRoutePredicateFactory

Between Route Predicate匹配在指定日期时间范围之内发生的请求;

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: time_between_route
uri: http://127.0.0.1:9001
predicates:
- Between=2020-01-01T00:00:00.000+08:00[Asia/Shanghai], 2024-01-01T00:00:00.000+08:00[Asia/Shanghai]

这里表示所有在​​北京时间2020年1月1日 00:00:00​​​之后 在​​北京时间2024年1月1日 00:00:00​​​之前 访问​​http://127.0.0.1:9999​​​地址的请求都会被路由到​​http://127.0.0.1:9001​​地址上;

此种方式通常对于维护时间窗口很适用,比如​​限时抢购​​场景。

2、Cookie相关(CookieRoutePredicateFactory)

Cookie Route Predicate 会接收两个参数:Cookie name、Java的正则表达式;谓词会根据Cookie name名称 和 其值 与配置的正则表达式做匹配,匹配上则执行路由,否则404。

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://127.0.0.1:9001
predicates:
- Cookie=saint,

这里表示请求的Cookie中属性名为saint,属性值符合​​正则规则​​​(handsome)的 访问​​http://127.0.0.1:9999​​​地址的请求都会被路由到​​http://127.0.0.1:9001​​地址上;

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用_spring_06

如果把Cookie中的​​saint=handsome​​移除,则会报错404;

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用_原力计划_07

3、Header相关(HeaderRoutePredicateFactory)

针对请求头Header做的路由和Cookie基本一样;

Header Route Predicate 会接收两个参数:Header name、Java的正则表达式;谓词会根据Header name 和 其值 与配置的正则表达式做匹配,匹配上则执行路由,否则404。

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://127.0.0.1:9001
predicates:
- Header=saint-header,

这里表示请求的Header名为saint-header,属性值符合​​正则规则​​​(\d+)的 访问​​http://127.0.0.1:9999​​​地址的请求都会被路由到​​http://127.0.0.1:9001​​地址上;

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用_java_08

如果把saint-header属性的值修改为不是全数字的数据,则会报错404;

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用_微服务_09

4、Host相关(HostRoutePredicateFactory)

Host Route Predicate 接收一个参数,参数类型是一组正则表达式形式的域名列表;每一个pattern是一个 ant 分隔的模板,用.号作为分隔符;它通过参数( Host header)中的主机地址作为匹配规则。

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://127.0.0.1:9001
predicates:
- Host=**.saint.com

这里表示请求的Header名为Host,属性值符合​​正则规则​​(.saint.com)的 访问http://127.0.0.1:9999地址的请求都会被路由到​http://127.0.0.1:9001​地址上;

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用_微服务_10


如果我们把Predicate写成​​**saint.com​​,则正则表达式中的仅能代表不包含​​.​​​的一个字符串,如果把Host配成​​www.saint.com​​,就会报404;

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用_原力计划_11

5、Method相关(MethodRoutePredicateFactory)

Method Route Predicate通过判断HTTP Methods(POST、GET、PUT、DELETE) 进行路由。

这里表示Method为GET、访问​​http://127.0.0.1:9999​​​地址的请求都会被路由到​​http://127.0.0.1:9001​​地址上;

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用_原力计划_12

如果请求的Method不是GET,比如POST http://127.0.0.1:9999/ 会报"404 Not Found";

【云原生&微服务>SCG网关篇四】Spring Cloud Gateway内置的11种PredicateFactory如何使用_云原生_13

6、Path相关(PathRoutePredicateFactory)

Path Route Predicate 接收一个匹配路径的参数来判断是否走路由。

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:9001 #访问地址
predicates:
- Path=/hello/**

这里表示访问​​http://127.0.0.1:9999/hello/​​​地址的请求都会被路由到​​http://127.0.0.1:9001/hello​​地址上;

如果是使用@Pathvariable注解动态构建请求,则可以写成Path=/hello/{name},name为动态入参

StripePrefix Filter

此外:Path Predicate 一般结合StripPrefix Filter使用。

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: simple_service_route
uri: http://127.0.0.1:9001
predicates:
# 路径匹配规则,向http://localhost:9999/gateway/simple-service/路径发送请求时,将会被转发到http://localhost:9001
- Path=/gateway/simple-service/**
filters:
# StripPrefix参数表示在将请求发送到下游之前从请求中剥离的路径个数。
# 如果设置StripPrefix=2,则当通过网关向/gateway/simple-service/hello发出请求时,对simple-service的请求将类似于/hello。
-

Predicate中配置的Path为​​/gateway/simple-service/**​​​,StripePrefix的值为2,当我们要通过gateway接收一个请求时,请求为:​​http://127.0.0.1:9999/gateway/simple-service/hello/sayHello​​​,则转发到​​http://127.0.0.1:9001​​​上的请求地址为:​​http://127.0.0.1:9001/hello/sayHello​​。

7、Query相关(QueryRoutePredicateFactory)

Query route predicate有两个参数,一个是必填的查询属性名,一个是选填的查询属性名对应的属性值(​​Java正则表达式​​);

1)仅匹配查询属性名

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:9001
predicates:
-

请求中包含 name 属性的参数时才会匹配路由,即:请求​​http://localhost:9999/**​​​ 会转发​​http://localhost:9001/**​​。

如果请求中不包含 name 属性的参数则会报"404 Not Found";

2)匹配查询属性名和属性名对应的值

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:9001
predicates:
- Query=name, .*saint

请求中包含 name 属性的参数、并且name参数对应的值符合正则表达式规则(​​.*saint​​​,即以saint结尾的字符串)时才会匹配路由,即:请求​​http://localhost:9999/**​​​ 会转发​​http://localhost:9001/**​​;否则会报"404 Not Found"。

8、请求IP地址相关(RemoteAddrRoutePredicateFactory)

RemoteAddr route predicate支持根据 ip 区间号段进行路由,其接受 cidr 符号 (IPv4 或 IPv6) 字符串的列表(最小大小为 1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子网掩码)。

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: remote_addr_route
uri: http://127.0.0.1:9001
predicates:
-

当且仅当请求IP是192.168.1.1/24网段,例如192.168.1.10,才会路由通过。

9、负载权重相关(WeightRoutePredicateFactory)

Weight route predicate 有两个参数:权重组group 和 权重比 weight(int类型),最终权重按组计算。可以看做是一种根据权重的负载均衡。

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: http://127.0.0.1:9001
predicates:
- Weight=group1, 8
- id: weight_low
uri: http://127.0.0.1:9002
predicates:
- Weight=group1, 2

这里表示在同一个权重组(group1)下有两个路由,​​http://127.0.0.1:9001​​​链接的权重为8,​​http://127.0.0.1:9002​​​链接的权重为2;假设过来10个请求,则8个请求打到​​http://127.0.0.1:9001​​​、2个请求打到​​http://127.0.0.1:9002​​。

10、组合使用

多个Predicate 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配。

server:
port: 9999
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: http://127.0.0.1:9001
predicates:
- After=2022-07-01T21:00:00.000+08:00[Asia/Shanghai]
- Method=GET
-

这里表示在2022年7月1日之后,参数中带有name属性的GET 类型请求可以匹配到路由。

三、总结和后续

本文我们把Spring Cloud Gateway内置的11种PredicateFactory都介绍了一下,下一篇文章我们聊一下如何自定义一个PredicateFactory。


举报

相关推荐

0 条评论