前面已经介绍了Netflix提供的网关路由组件Zuul,提供统一的API地址访问我们的服务,唯一不足的是Zuul采用的是Servlet的堵塞IO,性能比较低,而作为网关,性能是至关重要的,因此Spring 团队重新打造了一个网关路由组件Spring Cloud Gateway,他不仅仅支持HTTP协议,还支持websocket等协议,本篇我们将介绍Spring Cloud Gateway的使用。为了转型的方便Spring Cloud Gateway采取了与Zuul相似的策略,学习完Zuul很容易对Spring Cloud Gateway上手。引入Spring Cloud Gate也非常简单,只需要引入spring-cloud-starter-gateway即可:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
引入Maven依赖之后,如果我们不做任何自定义的扩展或者其他业务逻辑的实现,我们只需要编写启动类即可。
@SpringBootApplication
public class CloudGatewayApp {
public static void main(String[] args) {
SpringApplication.run(CloudGatewayApp.class, args);
}
}
在编写启动类之后,就像Zuul就需要配置相关网关路由,Spring Cloud Gateway采取了与Zuul类似而又不同的配置方式,在介绍Spring Cloud Gateway之前,我们先介绍Spring Cloud Gateway中的三个重要概念。我们先看下Spring Cloud Gateway的处理过程流程图:
根据上图,在Spring Cloud Gateway中有三个基本概念,路由、断言、过滤器。路由是网关的基础部分,路由信息由一个ID、一个目的URL、一组断言工厂和一组Filter过滤器组成,只有断言为真的时候,请求的URL和配置的路由匹配。断言是Java8中的断言函数,输入类型是Spring Framework 中的ServerWebExchange。它允许开发者在HTTP 请求中匹配任意内容,比如 headers和parameter。过滤器这些是使用特定工厂构建的Spring Framework GatewayFilter实例。在这里,可以在发送下游请求之前或之后修改请求和响应。如下我们配置一个简单的路由策略:
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes: #路由前缀
- id: csdn #id唯一标识
uri: https://www.csdn.net/ #转发的目的地址
predicates: #断言,path为/csdn的会转发到上面的地址
- Path=/csdn
server:
port: 8081
如上配置,与Zuul类似,很简单就能配置一个路由,我们启动服务之后,当我们访问http://localhost:8081/csdn的时候会显示csdn的页面,当然因为样式等加载失败,页面显示内容会不完整。这里只是一个简单的配置,后续我们会对Spring Cloud Gateway的路由配置进行详细讲解。下面我们要介绍的是Spring Cloud Gateway的基本原理。在Zuul中是使用Servlet拦截所有请求,然后根据配置的路由进行转发,因为Servlet的效率比较低,在Spring Cloud Gateway中使用了Spring提供的spring-webflux作为服务。如下图为SpringCloud 官方提供的请求流程图:
客户端向spring cloud gateway发出请求。如果Gateway Handler Mapping确定请求与路由匹配,则将其发送到Gateway Web Handler。此处理程序运行通过特定于请求的筛选器链发送请求。过滤器被虚线分开的原因是过滤器可能在代理请求发送之前或之后执行逻辑。执行所有“预”过滤器逻辑,然后发出代理请求。发出代理请求后,执行“post”过滤器逻辑。