• springCloudAlibaba之分布式网关组件---gateway


    网关

    微服务架构中一个系统会被拆分成多个微服务。那么作为客户端(前端)要如何去调用这么多的微服务?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去用。
    在这里插入图片描述

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

    • 每个业务都会需要鉴权、限流、权限校验、跨域等逻辑,如果每个业务都各自为站。自己造轮子实现一遍,完全没必要,完全可以抽离出来,放到一个统一的地方去做
      上面的问题可以借助网关来解决。
      在这里插入图片描述

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

    添加上API网关之后,系统变成三层结构,系统的架构图如下:
    在这里插入图片描述
    加入网关之后的架构图
    在这里插入图片描述

    spring cloud gateway

    • 功能特征
    • 基于spring5.0和springboot2.0进行构建
    • 动态路由:可以匹配任何请求属性
    • 支持路径重写
    • 集成服务发现(nacos、ereka)
    • 可集成流控降级功能(sentinel、hystrix)
    • 可以对路由指定易于编写的断言和过滤器
    • 路由
      路由是网关中最基础的部分,路由信息包括一个ID、一个目的URL、一组断言工厂、一组filter组成。如果断言为真,则说明请求的RUL和配置的路由匹配;
    • 断言
      Java8中的断言函数,gateway中的断言函数类型是spring5.0框架中的servletWebExchange,断言函数允许开发者去定义匹配http request中的任何信息,比如请求头和参数等。
    • 过滤器
      gateway中的filter分为Gateway Filter和Global Filter,filter可以对请求和响应处理
    • 工作原理
      spring cloud gateway的工作原理和zuul的差不多,最大的区别就是gateway的filter只有pre和post两种。

    gateway初体验

    添加依赖

       
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-gatewayartifactId>
            dependency>
    
    • 配置文件
    server:
      port: 8090
    # gateway配置
    spring:
      application:
        name: api-gateway
      cloud:
        #gateway配置
        gateway:
          #路由规则
          routes:
            - id: order_router #路由的唯一标识,路由到order
              uri: http://localhost:8081 #需要转发的地址
              #断言规则 用于路由规则的匹配
              predicates:
                - Path=/order-server/**
                  # http://localhost:8090/order-server/order/buyProduct 路由到↓
                  # http://localhost:8081/order-server/order/buyProduct
              filters:
                - StripPrefix=1 #内置过滤器,转发之前去掉第一层路径
                # http://localhost:8081/order-server/order/buyProduct 去掉后 ↓
                # http://localhost:8081/order/buyProduct
    

    gateway整合nacos

    你这个是springcloud gateway吧,我跟你说一下为什么这么写配置,是这样的,lb代表了负载均衡,有这个标志后,gateway就知道需要进行负载均衡,转发到lb://后面跟的服务名对应的某台服务器上,至于如何实现负载均衡,是通过负载均衡组件来的,比如ribbon或者springcloud-loadbalancer组件拿到服务列表,从而进行服务的转发。所以lb://,其实跟服务注册中心没有关系,就算不是nacos,用其它的,比如eureka,也是这么写lb://。

    server:
      port: 8090
    # gateway配置
    spring:
      application:
        name: api-gateway
      cloud:
        #nacos配置
        nacos:
          discovery:
            server-addr: 192.168.184.15:8848
            username: nacos
            password: nacos
        #gateway配置
        gateway:
          #路由规则
          routes:
            - id: order_router #路由的唯一标识,路由到order
              uri: lb://order-service #需要转发的地址 lb:使用nacos中的本地负载均衡策略
              #断言规则 用于路由规则的匹配
              predicates:
                - Path=/order-server/**
                # http://localhost:8090/order-server/order/buyProduct 路由到↓
                # http://localhost:8081/order-server/order/buyProduct
              filters:
                - StripPrefix=1 #内置过滤器,转发之前去掉第一层路径
                # http://localhost:8081/order-server/order/buyProduct 去掉后 ↓
                # http://localhost:8081/order/buyProduct
    

    简写方式

    当服务注册到nacos后,断言规则可以用服务名来进行匹配,此时配置可以进行简化(约定服务名和断言规则都从nacos获取)

    server:
      port: 8090
    # gateway配置
    spring:
      application:
        name: api-gateway
      cloud:
        #nacos配置
        nacos:
          discovery:
            server-addr: 192.168.184.15:8848
            username: nacos
            password: nacos
        #gateway配置
        gateway:
         discovery:
           locator:
             enabled: true #是否启动自动识别nacos服务(约定大于配置)
    
    • 测试
      此时访问:http://localhost:8090/order-service/order/buyProduct
      在这里插入图片描述

    内置路由断言工厂

    作用:当请求gateway的时候,使用断言对请求进行匹配,如果匹配成功就进行路由转发,如果匹配失败就返回404

    内置断言工厂

    在这里插入图片描述
    在这里插入图片描述

    • 基于Datetime类型的断言工厂
      此类型的断言根据时间做判断,主要有三个:
    • AfterRoutePredicateFactory:接收一个日期参数,判断请求日期是否晚于指定日期
    • BeforeRoutePredicateFactory:接收一个日期参数,判断请求日期是否早于指定日期
    • BetweenRoutePredicateFactory:接收一个日期参数,判断请求日是否在指定时间段内
      类型:zoneDateTime.now():System.out.println(ZonedDateTime.now());

    -After=2024-12-31T23:59:59.789+08:00[Asia/Shanghai]

    #第一版
    server:
      port: 8090
    # gateway配置
    spring:
      application:
        name: api-gateway
      cloud:
        #gateway配置
        gateway:
          #路由规则
          routes:
            - id: order_router #路由的唯一标识,路由到order
              uri: http://localhost:8081 #需要转发的地址
              #断言规则 用于路由规则的匹配
              predicates:
                - Path=/order/**
                - After=2024-12-31T23:59:59.789+08:00[Asia/Shanghai]
    
    • 基于请求头Headder的断言工厂
    • HeaderRoutePredicateFactory:接收两个参数,标题名称和正则表达式,判断请求Header是否具有给定名称且值与正则表达式匹配。
    • Header=X-Request-Id,\d+
    #第一版
    server:
      port: 8090
    # gateway配置
    spring:
      application:
        name: api-gateway
      cloud:
        #nacos配置
        nacos:
          discovery:
            server-addr: 192.168.184.15:8848
            username: nacos
            password: nacos
        #gateway配置
        gateway:
          #路由规则
          routes:
            - id: order_router #路由的唯一标识,路由到order
              uri: http://localhost:8081 #需要转发的地址
              #断言规则 用于路由规则的匹配
              predicates:
                - Path=/order/**
                - After=2023-12-31T23:59:59.789+08:00[Asia/Shanghai]
                - Header=X-Request-Id,\d+
    

    测试
    在这里插入图片描述
    在这里插入图片描述

    • 基于Method请求方法的断言工厂
    • MethodRoutePredicateFactory:接收一个参数,判断请求类型是否跟指定的类型匹配
    • Method=GET
    #第一版
    server:
      port: 8090
    # gateway配置
    spring:
      application:
        name: api-gateway
      cloud:
        #nacos配置
        nacos:
          discovery:
            server-addr: 192.168.184.15:8848
            username: nacos
            password: nacos
        #gateway配置
        gateway:
          #路由规则
          routes:
            - id: order_router #路由的唯一标识,路由到order
              uri: http://localhost:8081 #需要转发的地址
              #断言规则 用于路由规则的匹配
              predicates:
                - Path=/order/**
                - After=2023-12-31T23:59:59.789+08:00[Asia/Shanghai]
                - Header=X-Request-Id,\d+
                - Method=GET
    
    
    • 基于Query请求参数的断言工厂
    • QueryRoutePredicateFactory:接收两个参数,请求param和正则表达式,判断请求参数是否具有给定名称且值与正则表达式匹配。
    • Query=id,\d+
    #第一版
    server:
      port: 8090
    # gateway配置
    spring:
      application:
        name: api-gateway
      cloud:
        #nacos配置
        nacos:
          discovery:
            server-addr: 192.168.184.15:8848
            username: nacos
            password: nacos
        #gateway配置
        gateway:
          #路由规则
          routes:
            - id: order_router #路由的唯一标识,路由到order
              uri: http://localhost:8081 #需要转发的地址
              #断言规则 用于路由规则的匹配
              predicates:
                - Path=/order/**
                - After=2023-12-31T23:59:59.789+08:00[Asia/Shanghai]
                - Header=X-Request-Id,\d+
                - Method=GET
                - Query=id,\d+
    

    测试
    在这里插入图片描述

    自定义路由断言工厂

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

    1、必须是bean组件
    2、由于约定大于配置:类名必须加上RoutePredicateFactory作为结尾
    3、必须继承AbstractRoutePredicateFactory类
    4、必须声明一个静态内部类,声明属性来接收配置文件中对应的信息
    5、需要结合shortcutFieldOrder来进行绑定
    6、通过apply进行逻辑判断,true就是匹配成功,false匹配失败

    自定义路由工厂

    -checkAuth=zzq,如果配置文件中checkAuth=zzq,则匹配通过,否则匹配失败

    • 配置文件
    #第一版
    server:
      port: 8090
    # gateway配置
    spring:
      application:
        name: api-gateway
      cloud:
        #nacos配置
        nacos:
          discovery:
            server-addr: 192.168.184.15:8848
            username: nacos
            password: nacos
        #gateway配置
        gateway:
          #路由规则
          routes:
            - id: order_router #路由的唯一标识,路由到order
              uri: http://localhost:8081 #需要转发的地址
              #断言规则 用于路由规则的匹配
              predicates:
                - Path=/order/**
                - After=2023-12-31T23:59:59.789+08:00[Asia/Shanghai]
                - Header=X-Request-Id,\d+
                - Method=GET
                - Query=id,\d+
                - CheckAuth=zzq
    
    • 自定义代码
    @Component
    public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactory.Config> {
    
    
        public CheckAuthRoutePredicateFactory() {
            super(CheckAuthRoutePredicateFactory.Config.class);
        }
    
        /**
         * 绑定配置信息
         * @return
         */
        @Override
        public List<String> shortcutFieldOrder() {
            return Arrays.asList("name");
        }
    
        public Predicate<ServerWebExchange> apply(Config config) {
            return new GatewayPredicate() {
                @Override
                public boolean test(ServerWebExchange exchange) {
                    if (config.getName().equals("zzq")){
                        return true;
                    }
                    return false;
                }
            };
        }
    
        /**
         * 用于接收配置文件中 断言的信息
         */
        @Validated
        @Data
        public static class Config {
            private String name;
        }
    }
    
    
    • 测试
      在这里插入图片描述
    • 修改配置后
    #第一版
    server:
      port: 8090
    # gateway配置
    spring:
      application:
        name: api-gateway
      cloud:
        #nacos配置
        nacos:
          discovery:
            server-addr: 192.168.184.15:8848
            username: nacos
            password: nacos
        #gateway配置
        gateway:
          #路由规则
          routes:
            - id: order_router #路由的唯一标识,路由到order
              uri: http://localhost:8081 #需要转发的地址
              #断言规则 用于路由规则的匹配
              predicates:
                - Path=/order/**
                - After=2023-12-31T23:59:59.789+08:00[Asia/Shanghai]
                - Header=X-Request-Id,\d+
                - Method=GET
                - Query=id,\d+
                - CheckAuth=qwee
    
    • 测试
      在这里插入图片描述

    内置/自定义过滤器

    gateway内置了很多的过滤器工厂,我们通过一些过滤器工厂可以进行一些业务逻辑处理器,添加去除参数等。

  • 相关阅读:
    Java手写队列和案例拓展
    OpenMesh 获取面片的邻接面片
    经济计:宏观计算题
    神经网络入门教程,现代神经网络教程
    【力扣题解】2139. 得到目标值的最少行动次数
    细聊ASP.NET Core WebAPI格式化程序
    项目二---04.基于Nginx、keepalived的高可用集群之Apache Bench测试
    B-Tree 索引和 Hash 索引的对比
    2022还想上岸学习软件测试必看,测试老鸟的肺腑之言...
    Hadoop3:MapReduce中的Reduce Join和Map Join
  • 原文地址:https://blog.csdn.net/weixin_43216437/article/details/139716379