zoukankan      html  css  js  c++  java
  • Spring Cloud GateWay 服务网关

    一,简单的示例 入门

    参考地址:

    https://cloud.spring.io/spring-cloud-gateway/reference/html/

    http://www.ityouknow.com/spring-cloud

    1.1 pom.xml

    使用 Spring Cloud Finchley 版本,Finchley 版本依赖于 Spring Boot 2.0.6.RELEASE。

     <parent>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-parent</artifactId>
          <version>2.0.6.RELEASE</version>
          <relativePath/> <!-- lookup parent from repository -->
      </parent><dependencyManagement>
          <dependencies>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-dependencies</artifactId>
                  <version>Finchley.SR2</version>
                  <type>pom</type>
                  <scope>import</scope>
              </dependency>
          </dependencies>
      </dependencyManagement>

    项目需要使用的依赖包

      
     <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-gateway</artifactId>
      </dependency>

    Spring Cloud Gateway 是使用 netty+webflux 实现因此不需要再引入 web 模块。

    1.2 Spring Cloud Gateway 网关路由有两种配置方式:

    1.2.1 第一种如下在配置文件 yml 中配置

    入门application.yml配置

      
      server:
        port: 8083
      spring:
        cloud:
          gateway:
            routes:
            - id: 1
              uri: http://www.baidu.com
              predicates:
              - Path=/spring-cloud

    各字段含义如下:

    • id:我们自定义的路由 ID,保持唯一

    • uri:目标服务地址

    • predicates:路由条件,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。

    • filters:过滤规则,本示例暂时没用。

    上面这段配置的意思是,配置了一个 id 为 1的路由规则,当访问地址 http://localhost:8083/spring-cloud时会自动转发到地址:http://www.ityouknow.com/spring-cloud。配置完成启动项目即可在浏览器访问进行测试,当我们访问地址http://localhost:8083/spring-cloud 时会展示页面展示如下:

    1.2.2 第二种通过@Bean自定义 RouteLocator,如下在启动类 GateWayApplication 中添加方法 customRouteLocator() 来定制转发规则。
      
      @SpringBootApplication
      ​
      public class App {
      ​
          public static void main( String[] args ){
      ​
              SpringApplication.run(App.class, args);
      ​
          }
          @Bean
          public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
              return builder.routes()
                  .route("2", r -> r.path("/about")
                          .uri("http://ityouknow.com"))
                  .build();
          }
      }

    上面配置了一个 id 为2 的路由,当访问地址http://localhost:8083/about时会自动转发到地址:http://www.ityouknow.com/about和上面的转发效果一样,只是这里转发的是以项目地址/about格式的请求地址。

    二.通过时间匹配

    在 Spring Cloud Gateway 中 Spring 利用 Predicate 的特性实现了各种路由匹配规则,有通过 Header、请求参数等不同的条件来进行作为条件匹配到对应的路由。网上有一张图总结了 Spring Cloud 内置的几种 Predicate 的实现。

    2.1 Predicate 支持设置一个时间,在请求进行转发的时候,可以通过判断在这个时间之前或者之后进行转发。比如我们现在设置只有在2019年12月20日才会转发到百度的网站,在这之前不进行转发,我就可以这样配置:

      
      server:
        port: 8083
      spring:
        cloud:
          gateway:
            routes:
            - id: 3
              uri: http://www.baidu.com
              predicates:
              - After=2019-12-20T06:06:06+08:00[Asia/Shanghai] 

    Spring 是通过 ZonedDateTime 来对时间进行的对比,ZonedDateTime 是 Java 8 中日期时间功能里,用于表示带时区的日期与时间信息的类,ZonedDateTime 支持通过时区来设置时间,中国的时区是:Asia/Shanghai

    After Route Predicate 是指在这个时间之后的请求都转发到目标地址。上面的示例是指,请求时间在 2019年12月20日6点6分6秒之后的所有请求都转发到地址http://baidu.com+08:00是指时间和UTC时间相差八个小时,时间地区为Asia/Shanghai

    添加完路由规则之后,访问地址http://localhost:8083会自动转发到http://baidu.com

    2.2 Before Route Predicate 刚好相反,在某个时间之前的请求的请求都进行转发。我们把上面路由规则中的 After 改为 Before,如下:

     
      server:
        port: 8083
      spring:
        cloud:
          gateway:
            routes:
            - id: 3
              uri: http://www.ityouknow.com
              predicates:
              - Before=2019-12-10T11:06:06+08:00[Asia/Shanghai] 

    就表示在这个时间之前可以进行路由,在这时间之后停止路由,修改完之后重启项目如果当前时间已经过了设置时间再次访问地址http://localhost:8083,页面会报 404 没有找到地址。

    2.4 除过在时间之前或者之后外,Gateway 还支持限制路由请求在某一个时间段范围内,可以使用 Between Route Predicate 来实现。

    server:
      port: 8083
    spring:
      cloud:
        gateway:
          routes:
          - id: 3
            uri: http://www.ityouknow.com
            predicates:
            - Between=2018-12-20T11:06:06+08:00[Asia/Shanghai], 2019-12-10T12:06:06+08:00[Asia/Shanghai]

    这样设置就意味着在这个时间段内可以匹配到此路由,超过这个时间段范围则不会进行匹配。通过时间匹配路由的功能很酷,可以用在限时抢购的一些场景中。 以上是只会匹配到2019年12月10日11点6分6秒到2019年12月10日12点6分6秒之间的请求,访问地址:http://localhost:8083

    三.通过 Cookie 匹配

    Cookie Route Predicate 可以接收两个参数,一个是 Cookie name ,一个是正则表达式,路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行。

      server:
        port: 8083
      spring:
        cloud:
          gateway:
            routes:
            - id: 5
              uri: http://www.baidu.com
              predicates:
              - Cookie=ityouknow, kee.es

    使用 curl 测试,命令行输入:

       curl 192.168.1.206:8083 --cookie "ityouknow=kee.es"

    则会返回页面代码,如果cookie的值或者name对不上--cookie "ityouknow=kee.e",后台会报 404 错误。

    四.通过 Header 属性匹配

    Header Route Predicate 和 Cookie Route Predicate 一样,也是接收 2 个参数,一个 header 中属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行。

      server:
        port: 8083
      spring:
        cloud:
          gateway:
            routes:
            - id: 5
              uri: http://www.baidu.com
              predicates:
              - Header=X-Request-Id, d+

    d+表示一到多个数字 ,就是正则表达式里的用法

    使用 curl 测试,命令行输入:

      
      curl 192.168.1.206:8083 -H "X-Request-Id:666"

    则返回页面代码证明匹配成功。将参数-H "X-Request-Id:666"改为-H "X-Request-Id:hello"再次执行时返回404证明没有匹配。

    五.通过 Host 匹配

    Host Route Predicate 接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。它通过参数中的主机地址作为匹配规则。

      server:
        port: 8083
      spring:
        cloud:
          gateway:
            routes:
            - id: 5
              uri: http://www.baidu.com
              predicates:
              - Host=**.baidu.com

    使用 curl 测试,命令行输入:

    curl 192.168.1.206:8083 -H "Host:test5564.baidu.com"

    经测试以上 host 以.baidu.com结尾的均可匹配到 host_route 路由,去掉 host 参数则会报 404 错误。

    六.通过请求方式匹配(POST、GET、PUT、DELETE)

      
      server:
        port: 8083
      spring:
        cloud:
          gateway:
            routes:
            - id: 5
              uri: https://www.baidu.com
              predicates:
              - Method=GET

    使用 curl 测试,命令行输入:

      
    # curl 默认是以 GET 的方式去请求
    curl 192.168.1.206:8083

    测试返回页面代码,证明匹配到路由,

    以 POST 的方式请求测试, 返回 404 没有找到,证明没有匹配上路由

    七.通过请求路径匹配

    Path Route Predicate 接收一个匹配路径的参数来判断是否走路由。

      
      server:
        port: 8083
      spring:
        cloud:
          gateway:
            routes:
            - id: 7
              uri: http://www.baidu.com
              predicates:
              - Path=/hadoop/{segment}

    如果请求路径符合要求,则此路由将匹配,例如:/foo/1 或者 /foo/bar。

    使用 curl 测试,命令行输入:

      
    http://192.168.1.206:8083/hadoop/hello
      http://192.168.1.206:8083/hadoop/6969
      curl http://192.168.1.206:8083/had/6969

    经过测试第一和第二条命令可以正常获取到页面返回值,最后一个命令报404,证明路由是通过指定路由来匹配

    八.通过请求参数匹配

    Query Route Predicate 支持传入两个参数,一个是属性名一个为属性值,属性值可以是正则表达式。

    8.1 如下这样配置,只要请求中包含 token属性的参数即可匹配路由。

      
      server:
        port: 8083
      spring:
        cloud:
          gateway:
            routes:
            - id: 7
              uri: http://www.baidu.com
              predicates:
              - Query=token

    浏览器测试:

      https://www.baidu.com/?token=12

     

    8.2 指定参数

      
      server:
        port: 8083
      spring:
        cloud:
          gateway:
            routes:
            - id: 7
              uri: http://www.baidu.com
              predicates:
              - Query=token,1_grand

    浏览器测试:

      
      http://localhost:8083/?token=1_grand 

    要请求中包含 token属性的参数且参数的值只能是1_grand即可匹配路由,还可以正则的方式设置。

    九.通过请求 ip 地址进行匹配

    Predicate 也支持通过设置某个 ip 区间号段的请求才会路由,RemoteAddr Route Predicate 接受 cidr 符号(IPv4 或 IPv6 )字符串的列表(最小大小为1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子网掩码)。

    ipv4的子网掩码是:0~32之间

      server:
        port: 8083
      spring:
        cloud:
          gateway:
            routes:
            - id: 7
              uri: http://192.168.1.206:8081
              predicates:
              - RemoteAddr=192.168.1.206/32

    自己写了个测试项目:

      package com.web.kds.hadoop_kafka.Controller;
      ​
      import java.io.IOException;
      import javax.servlet.http.HttpServletResponse;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      import lombok.extern.slf4j.Slf4j;
      ​
      @Slf4j
      @RestController
      @RequestMapping("/TestCrolller")
      public class TestCrolller {
      ​
          @RequestMapping("/testfile")
          public void testfile(HttpServletResponse rps,String str) {
              rps.setContentType("application/json; charset=UTF-8");
              try {
                  log.info(""+str);
                  rps.getWriter().print(""+str);
              } catch (IOException e) {
                  e.printStackTrace();
              }
              
          }
          @RequestMapping("/file")
          public void file(HttpServletResponse rps,String str) {
              rps.setContentType("application/json; charset=UTF-8");
              try {
                  log.info(""+str);
                  rps.getWriter().print(""+str);
              } catch (IOException e) {
                  e.printStackTrace();
              }
              
          }
      }

    浏览器测试,将此地址设置为本机的 ip 地址进行测试:

      http://192.168.1.206:8083/hadoop_kafka/TestCrolller/testfile?str=6669999

    十.组合使用

    相同的Predicate也可以配置多个,请求的转发是必须满足所有的Predicate后才可以进行路由转发,组合使用示例如下所示:

      server:
        port: 8083
      spring:
        cloud:
          gateway:
            routes:
            - id: 8
              uri: http://192.168.1.206:8081
              predicates:
              - RemoteAddr=192.168.1.206/28
              - Query=token,hello
              - Query=str
              - Method=GET
              - RemoteAddr=192.168.1.56/24

    以上配置测试时需满足以下3个条件:

    ip:必须是192.168.1.206或者192.168.1.56

    Query:必须有token和str属性,且token的值还只能是“hello”

    Method:请求方式必须是GET请求

    浏览器测试:

     http://192.168.1.206:8083/hadoop_kafka/TestCrolller/file?token=hello&str=6585575

    总结:

    一个请求满足多个路由的谓词条件时,请求只会被首个成功匹配的路由转发 。

    Spring Cloud Gateway 使用非常的灵活,可以根据不同的情况来进行路由分发,在实际项目中可以自由组合使用。

  • 相关阅读:
    yum install mysql.i686
    firefox无法浏览flash的解决方案
    vb.net如何打开指定文件
    XML文件操作的简单类
    window server 安装与卸载
    常用的sql语句
    with进行递归表
    常用js
    调用Google的自动翻译
    MySQl 总结知识
  • 原文地址:https://www.cnblogs.com/KdeS/p/12024109.html
Copyright © 2011-2022 走看看