0506-Gateway

第一章 SpringCloudGateway概述

1.1 Gateway介绍

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

        SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 2.0之前的非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。

        Spring Cloud Gateway 的目标,不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。

        Spring Cloud Gateway 底层使用了高性能的通信框架Netty。

1.2 Gateway特征

  1. 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
  2. 集成 Hystrix 断路器
  3. 集成 Spring Cloud DiscoveryClient
  4. Predicates 和 Filters 作用于特定路由,易于编写的 Predicates 和 Filters
  5. 具备一些网关的高级功能:动态路由、限流、路径重写

1.3 Gateway相关术语解释

  1. Filter(过滤器):和Zuul的过滤器在概念上类似,可以使用它拦截和修改请求,并且对上游的响应,进行二次处理。过滤器为org.springframework.cloud.gateway.filter.GatewayFilter类的实例。
  2. Route(路由):网关配置的基本组成模块,和Zuul的路由配置模块类似。一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。
  3. Predicate(断言):这是一个 Java 8 的 Predicate,可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。断言的输入类型是一个 ServerWebExchange。

第二章 SpringCloudGateway架构

2.1 SpringCloud Zuul的IO模型

        Springcloud中所集成的Zuul版本,采用的是Tomcat容器,使用的是传统的Servlet IO处理模型;

        servlet由servlet container进行生命周期管理:container启动时构造servlet对象并调用servlet init()进行初始化;container关闭时调用servlet destory()销毁servlet;container运行时接受请求,并为每个请求分配一个线程(一般从线程池中获取空闲线程)然后调用service()。

        弊端:servlet是一个简单的网络IO模型,当请求进入servlet container时,servlet container就会为其绑定一个线程,在并发不高的场景下这种模型是适用的,但是一旦并发上升,线程数量就会上涨,而线程资源代价是昂贵的(上线文切换,内存消耗大)严重影响请求的处理时间。在一些简单的业务场景下,不希望为每个request分配一个线程,只需要1个或几个线程就能应对极大并发的请求,这种业务场景下servlet模型没有优势。

        所以Springcloud Zuul 是基于servlet之上的一个阻塞式处理模型,即spring实现了处理所有request请求的一个servlet(DispatcherServlet),并由该servlet阻塞式处理处理。所以Springcloud Zuul无法摆脱servlet模型的弊端。虽然Zuul 2.0开始,使用了Netty,并且已经有了大规模Zuul 2.0集群部署的成熟案例,但是,Springcloud官方已经没有集成改版本的计划了。

2.2 Webflux 服务器

        Spring在2017年下半年迎来了Webflux,Webflux的出现填补了Spring在响应式编程上的空白,Webflux的响应式编程不仅仅是编程风格的改变,而且对于一系列的著名框架,都提供了响应式访问的开发包,比如Netty、Redis等等。

        Webflux模式替换了旧的Servlet线程模型。用少量的线程处理request和response io操作,这些线程称为Loop线程,而业务交给响应式编程框架处理,响应式编程是非常灵活的,用户可以将业务中阻塞的操作提交到响应式框架的work线程中执行,而不阻塞的操作依然可以在Loop线程中进行处理,大大提高了Loop线程的利用率。Webflux虽然可以兼容多个底层的通信框架,但是一般情况下,底层使用的还是Netty;

2.3 Spring Cloud Gateway的处理流程

        客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。

2V8bX4.jpg

2.4 SpringCloudGateway配置方式

  1. 基于配置文件网关路由

    • 配置相关属性是数据结构如下

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      {
      "spring.cloud.routes":[
      {
      "id":"自定义的路由 ID,保持唯一",
      "uri":"目标服务地址",
      "predicates":[
      "路由条件,Predicate 接受输入参数,返回一个布尔值结果"
      ]
      }
      ]
      }
    • 配置文件基本案例(yaml个数):如下配置说明意思是:配置了一个 id 为 url-proxy-1的URI代理规则,路由的规则为:

      当访问地址http://localhost:8080/csdn/1.jsp时,会路由到上游地址https://blog.csdn.net/1.jsp

      1
      2
      3
      4
      5
      6
      7
      8
      spring:
      cloud:
      gateway:
      routes:
      -id: url-proxy-1
      uri: https://blog.csdn.net
      predicates:
      -Path=/csdn
  2. 基于代码的网关路由

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Configuration
    public class RouteConfigure{
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
    .route("path_route", r -> r.path("/csdn")
    .uri("https://blog.csdn.net"))
    .build();
    }
    }

第三章 SpringCloudGateway路由配置

2VJBz8.png

        Predicate 来源于 Java 8,是 Java 8 中引入的一个函数,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。

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

规则 实例 说明
Path - Path=/gate/,/rule/ ## 当请求的路径为gate、rule开头的时,转发到http://localhost:9023服务器上
Before - Before=2017-01-20T17:42:47.789-07:00[America/Denver] 在某个时间之前的请求才会被转发到 http://localhost:9023服务器上
After - After=2017-01-20T17:42:47.789-07:00[America/Denver] 在某个时间之后的请求才会被转发
Between - Between=2017-01-20T17:42:47.789-07:00[America/Denver],2017-01-21T17:42:47.789-07:00[America/Denver] 在某个时间段之间的才会被转发
Cookie - Cookie=chocolate, ch.p 名为chocolate的表单或者满足正则ch.p的表单才会被匹配到进行请求转发
Header - Header=X-Request-Id, \d+ 携带参数X-Request-Id或者满足\d+的请求头才会匹配
Host - Host=www.hd123.com 当主机名为www.hd123.com的时候直接转发到http://localhost:9023服务器上
Method - Method=GET 只有GET方法才会匹配转发请求,还可以限定POST、PUT等请求方式

3.1 通过请求参数匹配

https://www.cnblogs.com/crazymakercircle/p/11704077.html

3.2 通过 Header 属性匹配

3.4 通过 Host 匹配

3.5 通过请求方式匹配

3.6 通过请求路径匹配

3.7 通过请求 ip 地址进行匹配

3.8 组合使用

第四章 过滤器

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2020-2022 xiaoliuxuesheng
  • PV: UV:

老板,来一杯Java

支付宝
微信