gateway之断言的使用详解

文章目录

gateway产生的背景,为什么要是用gateway

一个系统会被拆分为多个微服务,作为客户端要如何去调用这么多的微服务?如果没有网关的存在,只能在客户端记录每个微服务的地址,然后分别去调用。

例如下图:

这样的架构,会存在着诸多的问题:

·每个业务都会需要鉴权、限流、权限校验、跨域等逻辑,如果每个业务都各自为战,自己造轮子实现一遍,完全可以抽出来,放到一个统一的地方去做。

·如果业务量比较简单的话,这种方式前期不会有什么问题,但随着业务越来越复杂,比如淘宝、亚马逊打开一个页面可能会涉及到数百个微服务协同工作,如果每一个微服务都分配一个域名的话,一方面客户端代码会很难维护,涉及到数百个域名,另一方面是连接数的瓶颈,通过抓包发现涉及到了数百个远程调用,这在移动端下会显得非常低效。

后期如果需要对微服务进行重构的话,也会变的非常麻烦,需要客户端配合你一起进行改造,比如商品服务,随着业务变的越来越复杂,后期需要进行拆分成多个微服务,这个时候对外提供

的服务也需要拆分成多个,同时需要客户端配合你进行改造

什么是网关

所谓的API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这甲实现,诸如认证、鉴权、监控、路由转发等等

添加上AP网关之后,系统的架构图变成了如下所示:

gateway 带来的好处

网关作为流量的入口,常用的功能包括路由转发,权限校验,限流等。

Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,定位于取代Netflix Zuul1.O。相比Zuul来说,Spring Cloud Gateway提供更优秀的性能,更强大的有功能

Spring Cloud Gateway是由WebFlux+Ney+Reactor实现的响应式的API网关。它不能在传统的servlet容器中工作,也不能构建成war包,

Spring Cloud Gateway旨在为微服务架构提供一种简单且有效的API路由的管理方式,并基于Filter方式提供网关的基本功能,例如说安全认证、监控、限流等等

功能特征

1、基于Spring Framework5,Project Reactor和Spring Boot2.0进行构建;

2、动态路由:能够匹配任何请求属性:

3、支持路径重写;

4、集成Spring Cloud服务发现功能(Nacos、Eruka);

5、可集成流控降级功能(Sentinel、.Hystrix);

6、可以对路由指定易于编写的Predicate(断言)和Filter(过滤器);## gateway是如何实现转发

gateway在项目中使用的依赖

父pom中使用的依赖:

java 复制代码
<properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
        <spring-cloud-alibaba.version>2.2.8.RELEASE</spring-cloud-alibaba.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.12.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
<!-- springcloud的版本依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <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>

gateway模块使用的依赖

java 复制代码
    <dependencies>
<!--        gateway依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

    </dependencies>

gateway的application.yml配置信息

java 复制代码
server:
  port: 8088
spring:
  main:
    web-application-type: reactive
  application:
    name: gateway
# gateway的配置
  cloud:
    gateway:
      #路由规则
      routes: #路由,数组[这里可以放置多个路由]
        #评分管理模块网关路由配置
        - id: shop_router #当前路由标识-要求唯一,默认是UUID;
          uri: http://localhost:8089 #请求最终要被转发的地址;
          order: 1 #路由的优先级------数字越小,代表路由的优先级越高
          predicates: #断言:(条件判断------转发请求要满足的条件)
#            - Path=/shop/** #当请求路径满族path指定的规则时,此路由信息才会正常转发;
#          filters: #过滤器,是在请求传递过程中对请求做一些手脚;
#            - StripPrefix=1 #在请求转发之前去掉一层路径
            - Path=/TestController/**
            - After=2019-12-31T23:59:59.789+08:00[Asia/Shanghai]
            - CheckAuth=gys

什么是断言

Spring Cloud Gateway(简称Gateway)支持断言Predicate功能,该断言功能是基于Spring WebFlux的HandlerMapping实现的。Gateway包含了很多路由断言工厂,并且这些工厂对应着HTTP请求的很多属性进行了处理,当客户端HTTP请求时,HandlerMapping会获取请求参数,并与Gateway中配置的Predicates进行比对,若满足规则就按规则约定进行路由放行,否则拒绝访问或报404错误。

断言分类

官网地址

内置

在配置文件中断言标签下配置的Path,After,都是内置断言,也就是gateway自己给提供的断言

例如:

基于Datatime类型的断言工厂

此类型的断言根据时间做判断,主要有三个:

AfterRoutePredicateFactory:接收一个日期参数,判断请求日期是否晚于指定日期

BeforeRoutePredicateFactory:接收一个日期参数,判断请求日期是否早于指定日期

BetweenRoutePredicateFactory:接收两个日期参数,判断请求日期是否在指定时间段内

自定义

自定义路由断言工厂需要继承AbstractRoutePredicateFactory类,重写apply方法的逻辑。在apply方法中可以通过exchange...getRequest()拿到ServerHttpRequest对象,从而可以获取到情求的参数、清求方式、清求头等信息,

注意点:

1、必须spring组件(必须是bean)

2.类必须加上RoutePredicateFactory作为结尾(约定大于配置)

3.必须继承AbstractRoutePredicateFactory

4.必须声明静态内部类(config)声明属性来接收配置文件中对应的断言的信息

通过shoutcutFieldOrder集合去返回输入内容的信息

5.需要结合shortcutFieldOrderi进行绑定

6,通过apply进行逻辑判断tue就是匹配成功false匹配失败

示例

java 复制代码
@Component
public class CheckAuthRoutePredicateFactorya extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactorya.Config> {


    public CheckAuthRoutePredicateFactorya() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("name");
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new GatewayPredicate() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                if (config.getName().equals("gys")){
                    return true;
                }
                return false;
            }
        };
    }


    /**
 * @description: 用于接收配置文件中断言的信息
 * @author: 
 * @date: 2023/9/19 19:52
 * @param:
 * @return:
 **/
    @Validated
    public static class Config {
        private String name;
        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

断言和过滤器的不同

1、功能不同:断言用于匹配请求的某些条件,例如请求路径、请求头、请求参数等,它决定了请求是否应该被路由到特定的目标服务。而过滤器用于对请求进行处理和转换,例如添加请求头、修改请求体、记录日志、实现认证授权等。

2、工作原理不同:断言通常用于路由选择的阶段,在接收请求时进行匹配,如果匹配成功,则将请求路由到相应的目标服务。而过滤器则是在请求路由之前或之后应用的,用于对请求进行预处理或后处理,它不会影响路由的选择。

3、使用场景不同:断言通常用于根据请求的某些属性进行路由选择,因此它更贴近网关的底层实现。而过滤器则更加灵活,可用于实现业务逻辑,例如认证授权、请求重试、流量控制等。

相关推荐
Yaml441 分钟前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~43 分钟前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616881 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
Channing Lewis1 小时前
salesforce case可以新建一个roll up 字段,统计出这个case下的email数量吗
数据库·salesforce
aloha_7891 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
睡觉谁叫~~~2 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
毕业设计制作和分享2 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
ketil272 小时前
Redis - String 字符串
数据库·redis·缓存
程序媛小果2 小时前
基于java+SpringBoot+Vue的旅游管理系统设计与实现
java·vue.js·spring boot