Gateway是在Spring生态系统之上构建的API网关服务,基于Spring 5、SpringBoot 2和Project Reactor等技术。Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能,例如反向代理,鉴权,日志,熔断、限流、重试等。Gateway基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
Gateway的特性
- 基于Spring 5、ProjectReactor和SpringBoot2.0进行构建。
- 动态路由:能够匹配任何请求属性。
- 可以对路由进行指定Predicate(断言)和Filter(过滤器)。
- 集成Hystrix的断路器功能。
- 集成Spring Cloud服务发现功能。
- 易于编写Predicate(断言)和Filter(过滤器)。
- 请求限流功能。
- 支持路径重写。
Gateway和Zuul的对比
在Zuul 1.X的时候采用的是Tomcat容器,使用的是传统的Servlet IO处理模型。而servlet的生命周期是由servlet container进行生命周期管理。
- container启动时构造servlet对象并调用servlet init()进行初始化
- container运行时接受请求,为每个请求分配一个线程(一般从线程池中获取空闲线程)然后调用service()
- container关闭时调用servlet destroy()销毁servlet
上述模式的缺点:
servlet是一个简单的网络IO模型,当请求进入servlet container时,servlet container就会为其绑定一个线程,在并发不高的场景下这种模型是适用的。但是一旦高并发,线程数量就会上涨,而线程资源的代价是昂贵的(上下文切换,内存消耗大)严重影响请求处理的时间。在一些简单业务场景下,不希望为每个request分配一个线程,只需要1个或几个线程就能应对极大并发的请求,这种业务场景下servlet模型没有优势。
所以Zuul 1.X是基于servlet之上的一个阻塞式处理模型,即Spring实现了处理所有request请求的一个servlet(DispatcherServlet)并由该Servlet阻塞式处理。所以SpringCloud Zuul无法摆脱servlet模型的弊端。
WebFlux
传统的Web框架,比如说Struts 2,SpringMVC等都是基于Servlet API与Servlet容器基础之上运行的。但是在Servlet 3.1之后有了异步非阻塞的支持。而WebFlux就是一个典型非阻塞异步框架,它的核心是基于Reactor的相关API实现的。相对于传统的Web框架来说,它可以运行在诸如Netty,Undertow及支持Servlet 3.1的容器上。Spring WebFlux是Spring 5.0引入的新的响应式框架,区别于SpringMVC,它不需要依赖Servlet API,它是完全异步非阻塞式的,并且基于Reactor来实现响应式流规范。
Gateway核心概念
- Route(路由),是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由。
- Predicate(断言),参考的是Java8的java.util.function.Predicate。开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由。
- Filter(过滤)指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
web请求通过一些匹配条件,定位到真正的服务节点。并且在这个转发过程前后,进行一些精细化控制。Predicate就是我们的匹配条件;而Filter就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标URI,就可以实现一个具体的路由了。
Gateway工作流程
客户端向Spring Cloud Gateway发出请求。然后在Gateway Handler Mapping中找到与请求相匹配的路由,将其发送待Gateway Web Handler。Handler在通过指定的过滤器来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务。Filter在“pre”类型的过滤器可以做参数效验、权限校验、流量监控、日志输出、协议转换等。在“post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等。
核心逻辑:路由转发+执行过滤链。