在前面博客学习了网关zuul,今天学下spring官方自带的网关spring cloud gateway。Zuul(1.x) 基于 Servlet,使用阻塞 API,它不支持任何长链接,如 WebSockets,Spring Cloud Gateway 使用非阻塞 API,支持 WebSockets,支持限流等新特性。java
Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。正则表达式
Spring Cloud Gateway 做为 Spring Cloud 生态系统中的网关,目标是替代 Netflix Zuul,其不只提供统一的路由方式,而且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。spring
相关概念:apache
Route(路由):这是网关的基本构建块。它由一个 ID,一个目标 URI,一组断言和一组过滤器定义。若是断言为真,则路由匹配。
Predicate(断言):这是一个 Java 8 的 Predicate。输入类型是一个 ServerWebExchange。咱们可使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。
Filter(过滤器):这是org.springframework.cloud.gateway.filter.GatewayFilter的实例,咱们可使用它修改请求和响应。
工做流程:浏览器
客户端向 Spring Cloud Gateway 发出请求。若是 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再经过指定的过滤器链来将请求发送到咱们实际的服务执行业务逻辑,而后返回。 过滤器之间用虚线分开是由于过滤器可能会在发送代理请求以前(“pre”)或以后(“post”)执行业务逻辑。缓存
Spring Cloud Gateway 的特征:安全
Spring Cloud Gateway 网关路由有两种配置方式,这里建议使用yml进行配置。cookie
咱们先实现一个简单的路由转发的demo:架构
1.引入依赖app
这里须要引入spring-cloud-starter-gateway。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.7.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>SpringCloudGatewayDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>SpringCloudGatewayDemo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.建立application.yml增长配置
server:
port: 8081
spring:
cloud:
gateway:
routes:
- id: neo_route
uri: http://www.cnblogs.com
predicates:
- Path=/5ishare
各字段含义以下:
id:咱们自定义的路由 ID,保持惟一
uri:目标服务地址
predicates:路由条件,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其余复杂的逻辑(好比:与,或,非)。
filters:过滤规则,本示例暂时没用。
上面这段配置的意思是,配置了一个 id 为 neo_route 的路由规则,当访问地址 http://localhost:8081/5ishare时会自动转发到地址:http://www.cnblogs.com/spring-cloud。配置完成启动项目便可在浏览器访问进行测试,当咱们访问地址http://localhost:8080/5ishare 时会展现https://www.cnblogs.com/5ishare页面。
路由规则
Spring Cloud Gateway 的功能很强大,咱们仅仅经过 Predicates 的设计就能够看出来,前面咱们只是使用了 predicates 进行了简单的条件匹配,其实 Spring Cloud Gataway 帮咱们内置了不少 Predicates 功能。
Spring Cloud Gateway 是经过 Spring WebFlux 的 HandlerMapping 作为底层支持来匹配到转发路由,Spring Cloud Gateway 内置了不少 Predicates 工厂,这些 Predicates 工厂经过不一样的 HTTP 请求参数来匹配,多个 Predicates 工厂能够组合使用。
Predicate 介绍
Predicate 来源于 Java 8,是 Java 8 中引入的一个函数,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其余复杂的逻辑(好比:与,或,非)。能够用于接口请求参数校验、判断新老数据是否有变化须要进行更新操做。
在 Spring Cloud Gateway 中 Spring 利用 Predicate 的特性实现了各类路由匹配规则,有经过 Header、请求参数等不一样的条件来进行做为条件匹配到对应的路由。网上有一张图总结了 Spring Cloud 内置的几种 Predicate 的实现。
经过时间匹配
Predicate 支持设置一个时间,在请求进行转发的时候,能够经过判断在这个时间以前或者以后进行转发。这里使用After来设置该时间以后转发,Before来设置该时间以前转发,Between来设置该时间区间端转发。在测试的过程当中开始设置After转发以后再修改另外两个Before和Between时不起做用了,须要清下浏览器缓存。
server:
port: 8081
spring:
cloud:
gateway:
routes:
- id: time_route
uri: http://www.cnblogs.com
predicates:
-After=2019-11-03T10:20:06+08:00[Asia/Shanghai]
# - Before=2019-11-03T10:55:06+08:00[Asia/Shanghai]
# - Between=2019-11-03T11:01:06+08:00[Asia/Shanghai], 2019-11-03T11:05:06+08:00[Asia/Shanghai]
经过 Cookie 匹配
Cookie Route Predicate 能够接收两个参数,一个是 Cookie name ,一个是正则表达式,路由规则会经过获取对应的 Cookie name 值和正则表达式去匹配,若是匹配上就会执行路由,若是没有匹配上则不执行。以下图所示,当在请求的Cookie中添加name=cuiyw时跳转到http://www.cnblogs.com,当不添加时报404错误。
经过 Header 属性匹配
Header Route Predicate 和 Cookie Route Predicate 同样,也是接收 2 个参数,一个 header 中属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行。以下图所示当设置X-Request-Id=6666时页面跳转正常,当设置为cuiyw时报404错。
server:
port: 8081
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://www.cnblogs.com
predicates:
- Cookie=name,cuiyw
- Header=X-Request-Id, \d+
经过 Host 匹配
Host Route Predicate 接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.
号做为分隔符。它经过参数中的主机地址做为匹配规则。这里没测试出来,暂时略过。
经过请求方式匹配
能够经过是 POST、GET、PUT、DELETE 等不一样的请求方式来进行路由,以下配置文件配置的是使用Get请求来进行路由,若是使用post则报404错误
server:
port: 8081
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://www.cnblogs.com
predicates:
- Method=GET
经过请求路径匹配
Path Route Predicate 接收一个匹配路径的参数来判断是否走路由。当输入http://localhost:8081/5ishare时报404错误,当输入http://localhost:8081/5ishare/p正常跳转。
server:
port: 8081
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://www.cnblogs.com
predicates:
- Method=GET
- Path=/5ishare/{segment}
经过请求参数匹配
Query Route Predicate 支持传入两个参数,一个是属性名一个为属性值,属性值能够是正则表达式。当输入http://localhost:8081/5ishare时报404错误,当输入http://localhost:8081/5ishare?name=cuiyw时跳转正常
经过请求 ip 地址进行匹配
Predicate 也支持经过设置某个 ip 区间号段的请求才会路由,RemoteAddr Route Predicate 接受 cidr 符号(IPv4 或 IPv6 )字符串的列表(最小大小为1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子网掩码)。这个目前没找到验证方法,暂时略过。
组合使用
在上面的例子有就能看到多个匹配组合在一块儿使用。例如经过Header属性匹配中设置了Cookie和Header。