• SpringCloud Gateway快速入门


    SpringCloud Gateway

    cloud笔记第一部分

    cloud笔记第二部分Hystrix

    SpringCloud Gateway是SpringCloud的一个全新的项目,基于Spring5+SpringBoot2和Project Reactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的API路由管理方式。

    为了提升网关性能,Gateway是基于WebFlux实现的,而WebFlux框架是使用了高性能的Reactor模式通信框架Netty

    Spring Cloud Gateway的目标是提供一种统一的路由方式且基于Filter的方式实现网关的基本功能,例如:安全,监控/指标,限流。

    Zull的工作模式与Gateway的对比

    Zuul采用的是Tomcat容器,使用的是传统的Servlet IO处理模型。

    这种模式的缺点是:当在并发不高的场景下这种模型是适用的,但是一旦高并发,线程数会大幅度增加,同时线程的创建销毁这个过程消耗的资源又是昂贵的,严重影响请求的处理时间,在一些简单的业务场景下,不希望为每个request分配一个线程,只需要1个或几个线程就能应对极大并发请求,这种业务场景下servlet模型没有优势,所以Zuul1版本是基于servlet上的阻塞式处理模型,因此无法解决这种弊端。

    在Servlet3.1之后有了异步非阻塞的支持。而WebFlux是一个典型的非阻塞的异步框架,他的核心是基于Reactor的相关API实现的。相对于传统的Web框架来说,它可以运行在Netty,Undertow以及支持Servlet3.1的容器上。

    SpringWebFlux是Spring5引入的新的响应式的框架,区别在于SpringMVC,他不需要依赖Servlet API,是完全的异步非阻塞,并基于Reactor来实现响应式流规范。

    Route(路由)

    路由是构建网关的基本模块,它是由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由。

    Predicate(断言)

    开发人员可以匹配HTTP请求中的所有内容,如果请求与断言相匹配则进行路由。

    Filter(过滤)

    指的是Spring框架GatewayFilter的实例,使用过滤器,可以在请求被路由前或者路由后进行修改。

    总结:客户端向Gateway发出请求,然后在Gateway Handle Mapping中找到与请求相匹配的路由,将其发送到gateway web Hnadle。

    Handle再通过指定的过滤器链来将请求发送到我们实际的服务之星业务逻辑,然后返回。过滤器可以在服务端接收请求前过滤,也可以在服务端向客户端发送响应后过滤。

    请求到达服务端前可以做:参数校验、权限校验、流量控制、日志输出、协议转换等。

    在服务端业务处理之后可以对响应的内容。头部进行修改,日志的输出,流量的监控都有重要作用。

    GateWay的配置方式

    1、在配置文件中直接配置

    server:
      port: 9527
    
    spring:
      application:
        name: cloud-gateway
      cloud:
        gateway:
          discovery:
            locator:
              enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
          routes:
            - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
              uri: http://localhost:8001          #匹配后提供服务的路由地址
    #          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
              predicates:
                - Path=/payment/get/**         # 断言,路径相匹配的进行路由
    
            - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
              uri: http://localhost:8001          #匹配后提供服务的路由地址
    #          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
              predicates:
                - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
        
    
    eureka:
      instance:
        hostname: cloud-gateway-service
      client: #服务提供者provider注册进eureka服务列表内
        service-url:
          register-with-eureka: true
          fetch-registry: true
          defaultZone: http://eureka7001.com:7001/eureka
    

    在使用Gateway做路由转发的功能时,需要引入的依赖。

      <dependencies>
                <!--gateway-->
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-gateway</artifactId>
                </dependency>
                <!--eureka-client-->
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
                </dependency>
                <!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
                <dependency>
                    <groupId>org.xzq.springcloud</groupId>
                    <artifactId>cloud-api-commons</artifactId>
                    <version>${project.version}</version>
                </dependency>
                <!--一般基础配置类-->
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-devtools</artifactId>
                    <scope>runtime</scope>
                    <optional>true</optional>
                </dependency>
                <dependency>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                    <optional>true</optional>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-test</artifactId>
                    <scope>test</scope>
                </dependency>
            </dependencies>
    

    需要注意的是,不需要引入web和actual,否则会启动失败。

    这时候访问http://localhost:8001/payment/get/1001,查询订单,同时也能通过

    http://localhost:9527/payment/get/1001访问到1001的订单信息。这就是当访问的URI符合配置文件中设置的predicate,就能通过Gateway转发。

    2、编写GatewayConfig配置类

    @Configuration
    public class GatewayConfig {
    
        @Bean
        public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
            RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
            // routes_id=route_guonei uri= http://news.baidu.com/guonei ; predicate Path=/guonei
            routes.route("route_guonei",r->r.path("/guonei")
                    .uri("http://news.baidu.com/guonei"))
                    .build();
            return routes.build();
        }
    }
    
    

    访问http://localhost:9527/guonei,会被路由到http://news.baidu.com/guonei

    通过微服务名实现动态路由

    默认情况下,Gateway会根据注册中心注册的服务列表,以注册中心上的微服务名为路径创建动态路由进行转发,从而实现动态路由的功能。

    开启从注册中心动态创建路由的功能,利用微服务名进行路由

    discovery:
    locator:
    enabled: true

    server:
      port: 9527
    
    spring:
      application:
        name: cloud-gateway
      cloud:
        gateway:
          discovery:
            locator:
              enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
          routes:
            - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
              
              uri: lb://cloud-payment-service #匹配后提供服务的路由地址
              predicates:
                - Path=/payment/get/**         # 断言,路径相匹配的进行路由
    
            - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
             
              uri: lb://cloud-payment-service #匹配后提供服务的路由地址
              predicates:
                - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
    
    
    eureka:
      instance:
        hostname: cloud-gateway-service
      client: #服务提供者provider注册进eureka服务列表内
        service-url:
          register-with-eureka: true
          fetch-registry: true
          defaultZone: http://eureka7001.com:7001/eureka
    
    
    
    

    常用的Predicate属性

    官方文档

    • After Route:在predicates下设置时间轴,在这个符合时间轴之后的请求才能路由。类型是ZoneDateTime
    spring:
      cloud:
        gateway:
          routes:
          - id: after_route
            uri: https://example.org
            predicates:
            - After=2017-01-20T17:42:47.789-07:00[America/Denver]
    
    • Before Route:匹配指定时间之前的请求,类型是ZoneDateTime。
    spring:
      cloud:
        gateway:
          routes:
          - id: before_route
            uri: https://example.org
            predicates:
            - Before=2017-01-20T17:42:47.789-07:00[America/Denver]
    
    • Between Route:在指定时间间隔内发起的请求才能匹配成功。predicate才是true。
    spring:
      cloud:
        gateway:
          routes:
          - id: between_route
            uri: https://example.org
            predicates:
            - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
    
    • Cookie Route:请求中需要包含指定的cookie才能匹配成功。
    spring:
      cloud:
        gateway:
          routes:
          - id: cookie_route
            uri: https://example.org
            predicates:
            - Cookie=chocolate, ch.p
    
    • Header Route:请求头参数中要包含指定键值对,否则不匹配。
    spring:
      cloud:
        gateway:
          routes:
          - id: header_route
            uri: https://example.org
            predicates:
            - Header=X-Request-Id, d+
    
    • Host Route:根据主机名进行匹配。
    spring:
      cloud:
        gateway:
          routes:
          - id: host_route
            uri: https://example.org
            predicates:
            - Host=**.somehost.org,**.anotherhost.org
    
    • Method Route: 符合指定的请求方法才能匹配成功。
    spring:
      cloud:
        gateway:
          routes:
          - id: method_route
            uri: https://example.org
            predicates:
            - Method=GET,POST
    
    • Path Route: 符合请求路径,路径中可以使用通配符。
    spring:
      cloud:
        gateway:
          routes:
          - id: path_route
            uri: https://example.org
            predicates:
            - Path=/red/{segment},/blue/**
    
    • Query Route: 包含指定参数才能匹配成功。
    spring:
      cloud:
        gateway:
          routes:
          - id: query_route
            uri: https://example.org
            predicates:
            - Query=green
    
    • Weight Route:根据请求的流量大小转发不同的服务
    spring:
      cloud:
        gateway:
          routes:
          - id: weight_high
            uri: https://weighthigh.org
            predicates:
            - Weight=group1, 8
          - id: weight_low
            uri: https://weightlow.org
            predicates:
            - Weight=group1, 2
    

    上面的例子就是将80%的请求流量转发到https://weighthigh.org,将20%的流量转发到https://weightlow.org。

    • Remote Route:匹配IP地址才能路由。
    spring:
      cloud:
        gateway:
          routes:
          - id: remoteaddr_route
            uri: https://example.org
            predicates:
            - RemoteAddr=192.168.1.1/24
    

    自定义过滤器

    自定义过滤器实现GlobalFilterOrdered接口,重写方法。

    @Component
    @Slf4j
    public class MyLogGatewayFilter implements Ordered, GlobalFilter {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 自定义过滤器,打印日志,如果请求参数中uname=null或者没有uname属性,不会放行请求
    
            log.info("----- com in MyLogGatewayFilter -----");
            String uname = exchange.getRequest().getQueryParams().getFirst("uname");
            if (uname == null) {
                log.info("----- uname 不能为空 -----");
                exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
                return exchange.getResponse().setComplete();
            }
            return chain.filter(exchange);
        }
    
        @Override
        public int getOrder() {
            return 0;
        }
    }
    

    如果请求参数没有加uname或者uname=null都不会放行请求。

    image-20200908203836937

  • 相关阅读:
    中科燕园GIS外包--移动GIS
    创建二维数组
    DSP开发中遇到的问题
    Unity 2D游戏开发教程之精灵的死亡和重生
    Unity 2D游戏开发教程之摄像头追踪功能
    Unity 2D游戏开发教程之2D游戏的运行效果
    Unity 2D游戏开发教程之使用脚本实现游戏逻辑
    Kail Linux渗透测试教程之免杀Payload生成工具Veil
    Kail Linux渗透测试教程之在Metasploit中扫描
    Kail Linux渗透测试教程之网络扫描和嗅探工具Nmap
  • 原文地址:https://www.cnblogs.com/itjiangpo/p/14181329.html
Copyright © 2020-2023  润新知