Spring Cloud Gateway 简明教程(02) - Predicate 匹配器使用示例

本篇主要介绍下 Spring Cloud Gateway 的匹配器 Predicate 的使用。

对于一个请求的路由,Spring Cloud Gateway 的处理过程是:

  • 遍历所有的路由
  • 针对每个路由,遍历其 Predicate 匹配器进行匹配,只有该路由的匹配器全部匹配才算匹配成功
  • 如果匹配失败,则跳到下一个路由;如果匹配成功,则忽略其余路由。

Spring Cloud Gateway 内置的匹配器提供了下面几种形式的匹配:

  • 基于权重的匹配
  • 基于时间的匹配,包括某个时间之前、之后,以及某个时间段之间
  • 基于请求的匹配,包括 Header、Cookie、Path、Method、Query Params、RemoteAddr、Host 几种方式。

下面对每种匹配方式进行简单的介绍和配置演示。

一. 基于权重的匹配

基于权重的匹配需要指明两个参数:

  • group:表示路由组。将多个需要按权重进行调度的路由声明为同一个 group
  • weight:设置权重,只能是整数

Spring Cloud Gateway 会基于一个组内权重的比例进行路由。

配置示例


spring:
  cloud:
    gateway:
      routes:
      # 基于权重匹配
      - id: student-route
        uri: http://localhost:8082
        predicates:
          - Path=/student/**
          - Weight=student-service-group, 8
      - id: student-canary-route
        uri: http://localhost:8083
        predicates:
          - Path=/student/**
          - Weight=student-service-group, 2
          

我针对学生服务部署了金丝雀 canary 版本,设置的权重为 2:8,表示将 20% 的请求路由到金丝雀版本中。

二. 基于时间的匹配

Spring Cloud Gateway 可以根据时间之前 Before、之后 After、之间 Between 三种方式进行路由匹配。配置的格式是 Java 的 ZonedDateTime 类型带时区信息的时间格式。

配置示例

  • Before、After 匹配

spring:
  cloud:
    gateway:
      routes:
        - id: student-route
          uri: http://localhost:8082
          predicates:
            - After=2020-04-20T17:42:47.789+08:00[Asia/Shanghai]
        - id: student-canary-route
          uri: http://localhost:8083
          predicates:
            - Before=2020-04-20T17:42:47.789+08:00[Asia/Shanghai]

这里表示对于学生服务,在东八区时间 2020-04-20 17:42:47 前将请求路由至金丝雀版本,在该时间之后路由到线上版本。

  • Between 匹配

Between 需要设置两个时间,表示在该段时间之内将请求路由到对应的服务,示例如下:


spring:
  cloud:
    gateway:
      routes:
        - id: student-canary-route
          uri: http://localhost:8083
          predicates:
            - Betwen=2020-04-18T17:42:47.789+08:00[Asia/Shanghai],2020-04-20T17:42:47.789+08:00[Asia/Shanghai]

一般来说时间类型的匹配还需要结合其他的匹配条件进行更加精确的匹配,不然只靠时间的话容易将不相关的服务的请求路由到错误的目的 URI 去。

三. 基于请求的匹配

1. 基于请求路径 Path 的匹配

最基本的就是按照路径进行请求的路由了。

配置示例

  • application.yml 文件配置

spring:
  cloud:
    gateway:
      routes:
        - id: teacher-route
          uri: http://localhost:8081
          predicates:
            - Path=/teacher/**
        - id: student-route
          uri: http://localhost:8082
          predicates:
            - Path=/student/**
  • Java 代码配置

@Configuration
public class RouteConfig {

    @Bean
    public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.path("/teacher/**")
                        .uri("http://localhost:8081/")
                        .id("teacher-route"))

                .route(r -> r.path("/student/**")
                        .uri("http://localhost:8082/")
                        .id("student-route"))
                .build();
    }
}

上面的配置表示将请求路径已 /teacher 开头的路由至教师服务,将请求路径以 /student 开头的请求路由至学生服务。

这里因为配置的 uri 是 IP:Port 的格式所以语义不是很直观,如果配合服务注册功能的这里的 uri 可以直接填写服务名,读起来就非常直观了,关于 Spring Cloud Gateway 结合服务注册功能使用将会在后面的文章中讲解。

2. 基于请求头 Header 的匹配

根据 HTTP 请求头 Header 的匹配需要设置两个字段:

  • name: 要匹配的 Header 字段名
  • regexp: 用来匹配的正则表达式(Java regular expression)

配置示例


spring:
  cloud:
    gateway:
      routes:
        - id: student-route
          uri: http://localhost:8082
          predicates:
            - Path=/student/**
            # 基于值的匹配,当 Header 中有 Canary 字段,值为 false 时,路由到生产环境的学生服务
            - Header=Canary, false
        - id: student-canary-route-01
          uri: http://localhost:8083
          predicates:
            - Path=/student/**
            # 基于值的匹配,当 Header 中有 Canary 字段,值为 true 时,路由到金丝雀版本的学生服务
            - Header=Canary, true
        - id: student-canary-route-02
          uri: http://localhost:8083
          predicates:
          - Path=/student/**
          # 基于正则的匹配,当 Header 中有 Request-ID 字段,值为一个或多个数字时,路由到金丝雀版本的学生服务
          - Header=Request-ID, \d+

3. 基于 Cookie 的匹配

和 Header 一样,根据 Cookie 进行匹配时有需要设置 nameregexp 两个字段,表示要匹配的 Cookie 字段和值。

配置示例


spring:
  cloud:
    gateway:
      routes:
        - id: student-route
          uri: http://localhost:8082
          predicates:
            - Path=/student/**
            # 基于值的匹配,当 Cookie 中有 Canary 字段,值为 false 时,路由到生产环境的学生服务
            - Cookie=Canary, false
        - id: student-canary-route-01
          uri: http://localhost:8083
          predicates:
            - Path=/student/**
            # 基于值的匹配,当 Cookie 中有 Canary 字段,值为 true 时,路由到金丝雀版本的学生服务
            - Cookie=Canary, true
        - id: student-canary-route-02
          uri: http://localhost:8083
          predicates:
          - Path=/student/**
          # 基于正则的匹配,当 Cookie 中有 STUDENT-ID 字段,值为一个或多个数字时,路由到金丝雀版本的学生服务
          - Cookie=STUDENT-ID, \d+

4. 基于请求方法 Method 的匹配

顾名思义,我们可以通过HTTP 的 Get、Post、Put 等方法进行路由匹配,这样可以将某一种类型的请求路由到特定的服务上。

配置示例


spring:
  cloud:
    gateway:
      routes:
        - id: student-route
          uri: http://localhost:8082
          predicates:
            - Path=/student/**
            # 将 Get 类型的请求全部路由到生产服务
            - Method=GET
        - id: student-canary-route-01
          uri: http://localhost:8083
          predicates:
            - Path=/student/**
            # 将 POST、PUT 类型的请求路由到金丝雀版本的服务商
            - Method=POST, PUT
            
5. 基于 Host 的匹配

如果 HTTP 的请求头中有 Host 字段,那么也可以基于该字段的值进行匹配,针对 Host 值的匹配不是通过正则表达式实现的,而是根据 Ant-style pattern 进行匹配。

配置示例


spring:
  cloud:
    gateway:
      routes:
        - id: student-route
          uri: http://localhost:8082
          predicates:
            - Host=**.student.com, **.grade.student.com
        - id: teacher-route
          uri: http://localhost:8081
          predicates:
            - Host=**.teacher.com
            

基于上面的配置,当请求的 Host 为 www.teacher.com 时 Gateway 会将请求路由到教师服务,如果是 www.student.com 、canary.student.com ,则会路由到学生服务。

6. 基于请求参数 Query Params 的匹配

针对参数的匹配,既可以只指定一个 name 字段名,表示只有对应名称的参数就匹配成功,也可以基于正则表达式指定一个匹配值,如果包含参数并且值也匹配才算匹配成功。

配置示例


spring:
  cloud:
    gateway:
      routes:
        - id: student-route
          uri: http://localhost:8082
          predicates:
            - Query=Tom
        - id: student-canary-route
          uri: http://localhost:8083
          predicates:
            - Query=Marry, abc.+
            

在上面的配置中,如果对学生服务的请求参数中带有 Tom 参数,则会将请求路由到 8082 端口,如果带有 Marry 参数并且值为 abc+任意字符那么会将请求路由到 8083 端口。

7. 基于请求IP RemoteAddr 的匹配

这里表示通过 Remote Address 进行匹配,这里定义一个列表,只要请求的 Remote Address 和列表中的任意一个 IP 地址匹配就表示匹配成功。

示例配置

spring:
  cloud:
    gateway:
      routes:
      - id: student-service
        uri: http://localhost:8082
        predicates:
        - RemoteAddr=192.168.1.1/24
        

上面配置表示如果请求来自于 192.168.1.1,则将请求转发到学生服务上。

以上就是 Spring Cloud Gateway 的 Predicatee 匹配器的一些用法,下一篇介绍 Filter 过滤器的用法和示例。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Gateway 提供了很多常用的过滤,下面列举一些比较常用的过滤使用示例: 1. 添加请求头过滤(AddRequestHeader Filter) 该过滤可以在请求头中添加指定的键值对,示例: ``` spring: cloud: gateway: routes: - id: add_request_header_route uri: http://www.baidu.com predicates: - Path=/baidu/** filters: - AddRequestHeader=X-Request-Id, 123 ``` 上面的配置表示在请求转发到 `http://www.baidu.com` 的时候,会在请求头中添加一个键值对 `X-Request-Id: 123`。 2. 去重请求头过滤(RemoveRequestHeader Filter) 该过滤可以去掉指定的请求头,示例: ``` spring: cloud: gateway: routes: - id: remove_request_header_route uri: http://www.baidu.com predicates: - Path=/baidu/** filters: - RemoveRequestHeader=X-Request-Id ``` 上面的配置表示在请求转发到 `http://www.baidu.com` 的时候,会去掉请求头中的 `X-Request-Id`。 3. 重写路径过滤(RewritePath Filter) 该过滤可以重写请求路径示例: ``` spring: cloud: gateway: routes: - id: rewrite_path_route uri: http://www.baidu.com predicates: - Path=/baidu/** filters: - RewritePath=/baidu/(?<segment>.*), /${segment} ``` 上面的配置表示在请求转发到 `http://www.baidu.com` 的时候,会将请求路径中的 `/baidu/` 去掉,例如请求 `/baidu/search` 会被重写为 `/search`。 4. 重试过滤(Retry Filter) 该过滤可以在请求失败的时候进行重试,示例: ``` spring: cloud: gateway: routes: - id: retry_route uri: http://www.baidu.com predicates: - Path=/baidu/** filters: - Retry=2, 5000, INTERNAL_SERVER_ERROR ``` 上面的配置表示当请求转发到 `http://www.baidu.com` 失败时,会进行最多 2 次重试,每次重试间隔 5000 毫秒,并且只有当返回状态码为 INTERNAL_SERVER_ERROR 时才会进行重试。 5. 限流过滤(RequestRateLimiter Filter) 该过滤可以对请求进行限流,示例: ``` spring: cloud: gateway: routes: - id: request_rate_limiter_route uri: http://www.baidu.com predicates: - Path=/baidu/** filters: - RequestRateLimiter=redis, #限流类型 key-resolver=#{T(org.springframework.cloud.gateway.handler.predicate.SpELKeyResolver).resolve('request_remote_address')}, #限流 key 算法 redis-rate-limiter.replenishRate=1, #令牌桶填充速率 redis-rate-limiter.burstCapacity=1 #令牌桶最大容量 ``` 上面的配置表示使用 Redis 实现限流,限制每个 IP 地址每秒只能请求一次。 以上是一些比较常用的 Spring Cloud Gateway 过滤使用示例,开发者可以根据自己的需求选择合适的过滤来实现特定的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值