• 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中使用的依赖:

    <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>
    
    • 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
    • 35
    • 36
    • 37
    • 38

    gateway模块使用的依赖

        <dependencies>
    <!--        gateway依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
    
        </dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    gateway的application.yml配置信息

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    什么是断言

    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匹配失败

    示例

    @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
    • 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
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    断言和过滤器的不同

    1、功能不同:断言用于匹配请求的某些条件,例如请求路径、请求头、请求参数等,它决定了请求是否应该被路由到特定的目标服务。而过滤器用于对请求进行处理和转换,例如添加请求头、修改请求体、记录日志、实现认证授权等。
    2、工作原理不同:断言通常用于路由选择的阶段,在接收请求时进行匹配,如果匹配成功,则将请求路由到相应的目标服务。而过滤器则是在请求路由之前或之后应用的,用于对请求进行预处理或后处理,它不会影响路由的选择。
    3、使用场景不同:断言通常用于根据请求的某些属性进行路由选择,因此它更贴近网关的底层实现。而过滤器则更加灵活,可用于实现业务逻辑,例如认证授权、请求重试、流量控制等。

  • 相关阅读:
    用Unity实现Bloom
    解决前端恶意代码侵入的一些思考
    AndroidStudio案例——跑马灯
    CTF-python爬虫学习笔记
    循环神经网络-LSTM
    postgresql-窗口函数
    使用 jMeter 对 SAP Spartacus 进行并发性能测试
    【安卓基础1】初识Android
    修改 Stable Diffusion 使 api 接口增加模型参数
    Stream.toList()和Collectors.toList()的性能比较
  • 原文地址:https://blog.csdn.net/weixin_45309155/article/details/133121405