定制化开发【Spring Cloud】 Gateway网关 上 路由断言规则详解

文章目录

依赖

		 <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-gateway</artifactId>        </dependency>
  • 1
  • 2
  • 3
  • 4

三大组件

  1. 路由

  2. 断言

  3. 过滤器

路由

定制化开发的基本组成,它由ID,目标URL,定制化开发断言和过滤器组成.定制化开发如果断言为true,定制化开发将匹配路由

断言

定制化开发只有断言成功的请求才定制化开发会匹配路由

过滤器

定制化开发可以对请求或响应进行处理

小Demo Gateway初次使用

定制化开发新建服务模块,提供 @GetMapping(“/say”) @GetMapping(“/say/one”) 定制化开发两个请求映射

@RestControllerpublic class HelloController {    @GetMapping("/say")    public String say()    {        return "HelloWord";    }    @GetMapping("/say/one")    public String sayOne()    {        return "HelloWord one";    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

定制化开发新建一个网关模块

定制化开发设置如下配置

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,定制化开发是一个集合        - id: apptest          # 路由的ID, 定制化开发没有固定规则但要求唯一,定制化开发建议配合服务名          uri: http://localhost:8080  # 定制化开发匹配后提供服务的路由地址          predicates:            - Path=/say/**
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

定制化开发启动两个服务

定制化开发我们先不经过网关访问服务 定制化开发测试是否能正常访问

定制化开发然后测试通过网关路由服务

至此 通过网关路由服务的一个demo完成了

工作原理

下图提供了Spring网关工作原理的高级概述:

客户端向网关发送请求,如果网关处理的映射请求与路由匹配,则将映射请求交给 GateWay Web Handler处理. Handler再通过相关的过滤器链将请求交给实际服务执行,最后返回

过滤器可以发送代理请求前执行,也可以在代理请求后执行

配置路由断言和过滤器

有两种方式可以来配置网关

1.快捷方式配置网关

快捷配置由过滤器名称,后跟一个等号=,用逗号(,)分隔的参数值来识别。

spring:  cloud:    gateway:      routes:      - id: after_route        uri: https://example.org        predicates:        - Cookie=mycookie,mycookievalue
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.将参数全部展开

完全展开的参数看起来更像带有名称/值对的标准yaml配置。 通常,会有一个name键和一个args键。 args键是配置断言或过滤器的键值对的映射

spring:  cloud:    gateway:      routes:      - id: after_route        uri: https://example.org        predicates:        - name: Cookie          args:            name: mycookie            regexp: mycookievalue
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

路由断言规则

1.时间作为匹配路由规则 After Before Between

1.1 The After Route Factory 时间之后

spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - After=2022-03-20T21:02:47.789-07:00[Asia/Shanghai]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

当请求的时间在断言时间之后,将匹配路由

我们配置的时间时 2022-03-20T21:02:47.789 在当前时间2022-03-20 21:07之前

也就是当前请求时间在我们断言的时间之后 此时能匹配路由

spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - After=2022-03-21T21:02:47.789-07:00[Asia/Shanghai]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

当前时间是 03-20 我们断言的时间时 03-21 则请求不能匹配当前路由

1.2 The Before Route Predicate Factory 时间之前

看了上面时间之后的例子 对于时间之前的你肯定立马就能明白是怎么回事

与After正好相反

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - Before=2022-03-20T21:02:47.789-07:00[Asia/Shanghai]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

请求的时间在断言设置的时间之后,不能匹配到当前请求,所有无法匹配路由

把断言时间设置为当前时间之后 再来测试下

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - Before=2022-03-22T21:02:47.789-07:00[Asia/Shanghai]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

1.3.After和Before两者比较

1.4 The Between Route Predicate Factory 两个时间之间

指定两个时间,用逗号分割,如果请求时间在这两个时间之间,将匹配路由

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - Between=2022-03-19T21:02:47.789-07:00[Asia/Shanghai],2022-03-22T21:02:47.789-07:00[Asia/Shanghai]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

此时请求时间为

能正常路由 如果请求时间不在设置的时间范围内

则不能匹配路由

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - Between=2022-03-22T21:02:47.789-07:00[Asia/Shanghai],2022-03-23T21:02:47.789-07:00[Asia/Shanghai]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.Cook作为匹配路由规则 Cookie

2.1 The Cookie Route Predicate Factory

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - Cookie=token,123
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

如果请求cookie中有name为token,且值为123将匹配当前路由

name和value有一个不一样都不能成功路由

name和value都相同 则能成功路由

3.请求头作为匹配路由规则 Header

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - Header=token,123
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

请求对象的请求头中 如果有name为token,且值为123,将匹配当前路由

改用postman测试

如图 测试请求头没有name为token value为123 的请求头信息 则不能匹配路由

当请求头中有 name为token 值为 123的请求头信息时,能匹配到当前路由

4.Host作为匹配路由规则 Host

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - Host=**.haha.com:81
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

先修改本机host文件

127.0.0.1   qq.haha.com127.0.0.1   qq.haha.cn
  • 1
  • 2

访问 http://qq.haha.com:81/say 能匹配到路由

改成 cn 则不能匹配到路由

5.请求方法作为匹配路由规则 Method

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - Method=GET,POST
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

GET和PUT请求都能匹配到路由

如果我们换成PUT请求则不能匹配到路由

6.路径作为匹配路由规则 Path

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - Path=/say
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

访问 /say 能匹配到路由

多加一级路径则不能匹配到路由

可以正则 改成 /say/**

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - Path=/say/**
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

此时无论访问 /say 还是 /say/one都能匹配到路由

7.查询参数作为匹配路由规则 Query

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - Query=skuID
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

如果只写一个参数 则意思为 查询参数有skuID则匹配当前路由

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8080  # 匹配后提供服务的路由地址          predicates:            - Query=skuID,11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

如果两个参数,用逗号分割 则意思为 查询参数为skuID ,且值为11 匹配当前路由

注意 两个条件都必须满足 且请求方式与服务请求映射的方式一致

如果skuID 不为 11 也不能匹配到当前路由

8.权重作为匹配路由规则 Weight

server:  port: 81spring:  cloud:    gateway:      routes:   # 配置路由,是一个集合        - id: apptest1         # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:80  # 匹配后提供服务的路由地址          predicates:            - Path=/say/**            - Weight=group,5        - id: apptest2          # 路由的ID, 没有固定规则但要求唯一,建议配合服务名          uri: http://localhost:8081  # 匹配后提供服务的路由地址          predicates:            - Path=/say/**            - Weight=group,5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

有两个路由ID 二者根据权重匹配路由 都在一个权重分组中 且权重都为5 这样匹配到/say/** 的百分之五十 请求交给80端口,另外的交给8081端口

复制一个服务,并输出打印当前服务的端口号

package gateway.controller;import lombok.Data;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** * @author sz * @DATE 2022/3/20  20:15 */@Data@RestControllerpublic class HelloController {    @Value("${server.port}")    public String serverPort;    @GetMapping("/say")    public String say()    {        return "HelloWord   "+serverPort;    }    @GetMapping("/say/one")    public String sayOne()    {        return "HelloWord one";    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发