IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【Spring Cloud】 Gateway网关 上 路由断言规则详解 -> 正文阅读

[Java知识库]【Spring Cloud】 Gateway网关 上 路由断言规则详解

依赖

		 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

三大组件

  1. 路由

  2. 断言

  3. 过滤器

路由

网关的基本组成,它由ID,目标URL,断言和过滤器组成.如果断言为true,将匹配路由

断言

只有断言成功的请求才会匹配路由

过滤器

可以对请求或响应进行处理

小Demo Gateway初次使用

新建服务模块,提供 @GetMapping("/say") @GetMapping("/say/one") 两个请求映射

@RestController
public class HelloController {

    @GetMapping("/say")
    public String say()
    {
        return "HelloWord";
    }

    @GetMapping("/say/one")
    public String sayOne()
    {
        return "HelloWord one";
    }

}

新建一个网关模块

设置如下配置

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

启动两个服务

image-20220320203932339

我们先不经过网关访问服务 测试是否能正常访问

image-20220320204435940

然后测试通过网关路由服务

image-20220320204518403

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

工作原理

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

image-20220320204705420

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

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

配置路由断言和过滤器

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

1.快捷方式配置网关

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

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Cookie=mycookie,mycookievalue

2.将参数全部展开

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

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - name: Cookie
          args:
            name: mycookie
            regexp: mycookievalue

路由断言规则

Spring Cloud GateWay 路由断言规则

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

1.1 The After Route Predicate Factory 时间之后

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

image-20220320210727992

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

我们配置的时间时 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]

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

idea64_kT6F53Db4Q

1.2 The Before Route Predicate Factory 时间之前

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

与After正好相反

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

image-20220320210727992

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

image-20220320212018901

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

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

idea64_zclceImqkS

1.3.After和Before两者比较

image-20220320212422404

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

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

server:
  port: 81
spring:
  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]

此时请求时间为

image-20220320212716724

image-20220320212721973

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

则不能匹配路由

server:
  port: 81
spring:
  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]

image-20220320212809655

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

2.1 The Cookie Route Predicate Factory

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

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

image-20220320213341759

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

image-20220320213759651

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

image-20220320213831912

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

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

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

改用postman测试

image-20220320214449264

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

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

image-20220320214542684

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

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

先修改本机host文件

127.0.0.1   qq.haha.com
127.0.0.1   qq.haha.cn

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

image-20220320220006870

改成 cn 则不能匹配到路由

image-20220320220031733

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

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

image-20220320220307465

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

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

image-20220320220348535

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

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

访问 /say 能匹配到路由

image-20220320220457134

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

可以正则 改成 /say/**

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

image-20220320220612927

image-20220320220619846

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

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

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

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

image-20220320221048071

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

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

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

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

image-20220320221201786

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

server:
  port: 81
spring:
  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

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

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

image-20220320221525601

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
@RestController
public 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";
    }

}

image-20220320222254682

Postman_LhqOquGtIj

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-22 20:22:50  更:2022-03-22 20:22:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:50:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码