• springcloud学习(五)之GateWay


    GateWay简介

    网关(GateWay)

    局域⽹中就有⽹关(翻译过来就叫做GateWay)这个概念,局域⽹接收或者发送数据出去通过这个⽹关,⽐如⽤Vmware虚拟机软件搭建虚拟机集群的时候,往往我们需要选择IP段中的⼀个IP作为⽹关地址。
    我们学习的GateWay(Spring Cloud GateWay),它只是众多⽹关解决⽅案中的⼀种,是微服务架构中的重要组成部分

    Spring Cloud GateWay

    Spring Cloud GateWay是Spring Cloud的⼀个全新项⽬,⽬标是取代Netflix Zuul,它基于
    Spring5.0+SpringBoot2.0+WebFlux(基于⾼性能的Reactor模式响应式通信框架Netty,异步⾮阻塞模型)等技术开发,性能⾼于Zuul,官⽅测试, GateWay是Zuul的1.6倍,旨在为微服务架构提供⼀种简单有效的统⼀的API路由管理⽅式。
    Spring Cloud GateWay不仅提供统⼀的路由⽅式(反向代理)并且基于 Filter(定义过滤器对请求过滤,完成⼀些功能) 链的⽅式提供了⽹关基本的功能,例如:鉴权、流量控制、熔断、路径重写、⽇志监控等。

    GateWay的使用

    新建GateWay网关项目,由于gateway不需要引⼊starter-web模块,需要引⼊web-flux,而咱们之前的父工程里面有web组件,所以我们不能以lagou-parent为父工程建立gateway。

     <!--GateWay ⽹关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--引⼊webflux-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
    

    application.yml中做一些关于路由规则的配置:

    Spring:
      application:
        name: lagou-cloud-gateway
      cloud:
          gateway:
            routes: # 路由可以有多个
              - id: service-autodeliver-router # 我们⾃定义的路由 ID,保持唯⼀
                uri: http://127.0.0.1:8090 # ⽬标服务地址 ⾃动投递微服务(部署多实例)
            #动态路由: uri配置的应该是⼀个服务名称,⽽不应该是⼀个具体的服务实例的地址
            # gateway⽹关从服务注册中⼼获取实例信息然后负载后路由
                predicates: # 断⾔:路由条件, Predicate 接受⼀个输⼊参数,返回⼀个布尔值结果。该接⼝包含多种默认⽅法来将 Predicate 组合成其他复杂的逻辑(⽐如:与,或,⾮)。
                  - Path=/autodeliver/**
              - id: service-resume-router # 我们⾃定义的路由 ID,保持唯⼀
                uri: http://127.0.0.1:8081 # ⽬标服务地址
            #http://localhost:9002/resume/openstate/1545132
            #http://127.0.0.1:8081/openstate/1545132
                predicates: # 断⾔:路由条件, Predicate 接受⼀个输⼊参数,返回⼀个布尔值结果。该接⼝包含多种默 认⽅法来将Predicate 组合成其他复杂的逻辑(⽐如:与,或,⾮)。
                  - Path=/resume/**
                filters:
                  - StripPrefix=1
    

    正常访问服务消费者8090的地址是
    http://localhost:8090/autodeliver/checkStateTimeoutFallBack/1545132

    通过网关配置代理之后的地址:
    http://localhost:9002/autodeliver/checkStateTimeoutFallBack/1545132

    动态路由

    上面我们是直接写死了目标服务的请求地址,这样对于我们集群部署多个服务是不行的,我们应该改造成从eureka服务注册中心获取服务列表并进行访问,即所谓的动态路由。
    动态路由配置方式:url: lb://在eureka注册的服务名称
    lb表示从注册中心获取服务,后面是需要转发的服务名称。
    例如:

    uri: lb://lagou-service-resume
    

    因为需要从注册中心获取服务列表,所以需要在pom.xml中添加eureka的客户端依赖。
    测试:

    可以看到网关分发请求到不同的服务,实现了动态路由。

    GateWay过滤器

    从过滤器⽣命周期(影响时机点)的⻆度来说,主要有两个pre和post:

    生命周期时机点 作用
    pre 这种过滤器在请求被路由之前调⽤。我们可利⽤这种过滤器实现身份验证、在集群中选择 请求的微服务、记录调试信息等
    post 这种过滤器在路由到微服务以后执⾏。这种过滤器可⽤来为响应添加标准的 HTTPHeader、收集统计信息和指标、将响应从微服务发送给客户端等。

    从过滤器类型的⻆度, Spring Cloud GateWay的过滤器分为GateWayFilter和GlobalFilter两种:

    过滤器类型 影响范围
    GateWayFilter 应用到单个路由上
    GlobalFilter 应用到所有路由上

    比如GateWayFilter可以去掉url中的占位后再转发路由,如下:

    - id: service-resume-router # 我们⾃定义的路由 ID,保持唯⼀
                #uri: http://127.0.0.1:8081 # ⽬标服务地址
                uri: lb://lagou-service-resume # ⽬标服务地址
            #http://localhost:9002/resume/openstate/1545132
            #http://127.0.0.1:8081/openstate/1545132
                predicates: # 断⾔:路由条件, Predicate 接受⼀个输⼊参数,返回⼀个布尔值结果。该接⼝包含多种默 认⽅法来将Predicate 组合成其他复杂的逻辑(⽐如:与,或,⾮)。
                  - Path=/resume/**
                filters:
                  - StripPrefix=1
    

    和前面的动态路由相比,主要是添加了下面的参数:

     filters:
                  - StripPrefix=1
    

    StripPrefix这个参数的意思是去掉访问url的第一个参数,再进行匹配。
    比如http://localhost:9002/resume/openstate/1545132这个请求,会匹配目标服务的http://127.0.0.1:8081/openstate/1545132

    自定义全局过滤器实现IP访问限制(黑白名单功能)

    思路:请求过来时,判断发送请求的客户端的ip,如果在⿊名单中,拒绝访问.
    ⾃定义GateWay全局过滤器时,我们实现Global Filter接⼝即可,通过全局过滤器可以实现⿊⽩名单、限流等功能。
    在网关服务中自定义全局过滤器:

    @Slf4j
    @Component
    public class BlackListFilter implements GlobalFilter, Ordered {
    
    
        private static List<String> blackList=new ArrayList<>();
        static {
            blackList.add("0:0:0:0:0:0:0:1");//模拟本机地址
        }
    
        /**
         * 过滤器核⼼⽅法
         * @param exchange 封装了request和response对象的上下⽂
         * @param chain ⽹关过滤器链(包含全局过滤器和单路由过滤器)
         * @return
         */
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 思路:获取客户端ip,判断是否在⿊名单中,在的话就拒绝访问,不在的话就放⾏
              // 从上下⽂中取出request和response对象
            ServerHttpRequest request = exchange.getRequest();
            ServerHttpResponse response = exchange.getResponse();
    
    // 从request对象中获取客户端ip
            String clientIp = request.getRemoteAddress().getHostString();
            // 拿着clientIp去⿊名单中查询,存在的话就拒绝访问
            if(blackList.contains(clientIp)){
                //// 拒绝访问,返回
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                log.debug("------>Ip:"+clientIp+" 在黑名单中,被拒绝访问!");
                String data="Request be denied!!";
                DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());
                return response.writeWith(Mono.just(wrap));
            }
    
            // 合法请求,放⾏,执⾏后续的过滤器
            return chain.filter(exchange);
        }
    
        /**
         * 返回值表示当前过滤器的顺序(优先级),数值越⼩,优先级越⾼
         * @return
         */
        @Override
        public int getOrder() {
            return 0;
        }
    }
    
    

    效果:

    GateWay高可用

    ⽹关作为⾮常核⼼的⼀个部件,如果挂掉,那么所有请求都可能⽆法路由处理,因此我们需要做
    GateWay的⾼可⽤。
    GateWay的⾼可⽤很简单: 可以启动多个GateWay实例来实现⾼可⽤,在GateWay的上游使⽤Nginx等负载均衡设备进⾏负载转发以达到⾼可⽤的⽬的。
    举例:
    启动多个GateWay实例(假如说两个,⼀个端⼝9002,⼀个端⼝9003),剩下的就是使⽤Nginx等完成负载代理即可。示例如下:

    upstream gateway {
    server 127.0.0.1:9002;
    server 127.0.0.1:9003;
    }
    location / {
    proxy_pass http://gateway;
    }
    

    案例源码

    gateway案例源码地址:gateway案例源码地址

    欢迎访问我的博客:https://www.liuyj.top

  • 相关阅读:
    CentOS7源码安装 mplayer-1.1
    CentOS6开关机日志查询
    Redis GUI客户端
    CST & UTC时间差
    FreeBSD10.0 PXE安装
    PostgreSQL9.6源码安装
    phpPgAdmin-5.1安装配置
    js截取文件名不带后缀
    在MongoDB中修改数据类型
    win10怎么修改DNS
  • 原文地址:https://www.cnblogs.com/liuyj-top/p/14233110.html
Copyright © 2020-2023  润新知