一、介绍
网关是系统唯一对外的入口,介于客户端与服务器端之间,用于对请求进行鉴权、限流、 路由、监控等功能。
GateWay中有三个重要的术语,分别为route(路由)、predicate(断言)、filter(过滤器)
- 路由:网关的基本构建块。它由一个路由ID、一个目标URI、一组断言和一组过滤器组成。如果聚合谓词(断言)为true,则匹配路由,将请求将经由过滤器路由到目标URI。
- 断言:断言就是一个条件判断。根据当前的HTTP请求进行指定规则的匹配,如HTTP请求头, 请求时间等。只有当匹配上断言规则时,断言才为true,此时HTTP请求才会被直接路由到目标地址(目标服务器),或先路由到某过滤器链,经过过滤器链的层层处理后,再路由到相应的目标地址(目标服务器)。断言参考的是Java 8中的java.util.function.Predicate
- 过滤器:对请求进行处理的逻辑部分。当请求的断言为true时,会被路由到设置好的过滤器, 以对请求或响应进行处理。例如,可以为请求添加一个请求参数,或对请求URI进行修改,或为响应添加Header等。总之,就是对请求或响应进行处理。
二、工作原理
下图为Spring Cloud Gateway工作的概述:
客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定请求与路由匹配,则会将其发送到网关Web处理程序。此处理程序通过特定于请求的筛选器链来运行请求。过滤器被虚线分隔的原因是过滤器可以在发送代理请求之前和之后运行逻辑。执行所有“预”过滤器逻辑。然后进行代理请求。在发出代理请求后,将运行“post”过滤器逻辑。
注意:在没有端口的路由中定义的URI分别获得HTTP和HTTPS URI的默认端口值80和443。
三、使用GateWay
使用GateWay有两种方式,一种是通过配置文件去配置route、predicate、filter,以实现网关的作用,这种方式叫做配置式路由;另一种方式式通过编码的方式去配置route、predicate、filter,以实现网关的作用,这种方式叫做API路由。
3.1 配置式路由
3.1.1 添加依赖
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<java.version>17</java.version>
<spring-cloud.version>2022.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2022.0.0.0-RC2</spring-cloud-alibaba.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.6</version>
<relativePath/>
</parent>
<dependencies>
<!-- Spring Cloud GateWay依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
3.1.2 配置文件
配置式路由要在配置文件中配置route、predicate、filter,以实现网关的作用。
server:
port: 9000
spring:
cloud:
gateway:
routes:
- id: baidu_route
uri: https://baidu.com
predicates:
- Path=/bd
- id: taobao_route
uri: https://taobao.com
predicates:
- Path=/tb
- id: jingdong_route
uri: https://jd.com
predicates:
- Path=/jd
3.1.3 测试
运行启动类,在浏览器地址栏中输入http://localhost:9000/bd,访问会自动跳转到https://www.baidu.com/bd; 在浏览器地址栏中输入http://localhost:9000/tb,访问会自动跳转到https://www.baidu.com/tb; 在浏览器地址栏中输入http://localhost:9000/jd,访问会自动跳转到https://www.baidu.com/jd。
说明:只要跳转到了对应的链接就是成功了,页面出错是没有对应的网站信息!
3.2 API路由
3.2.1 添加依赖
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<java.version>17</java.version>
<spring-cloud.version>2022.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2022.0.0.0-RC2</spring-cloud-alibaba.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.6</version>
<relativePath/>
</parent>
<dependencies>
<!-- Spring Cloud GateWay依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
3.2.2 配置文件
server:
port: 9000
3.2.3 API配置
API路由要通过编码的方式去配置route、predicate、filter,以实现网关的作用。
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator BaiDuRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("baidu_route", predicateSpec -> predicateSpec.path("/bd")
.uri("https://baidu.com"))
.route("jd_route", predicateSpec -> predicateSpec.path("/jd")
.uri("https://jd.com"))
.route("tb_route", predicateSpec -> predicateSpec.path("/tb")
.uri("https://taobao.com"))
.build();
}
}
测试方法与配置式路由相同。
四、路由断言工厂
Spring Cloud Alibaba GateWay的路由断言工厂-CSDN博客
五、网关过滤工厂
Spring Cloud Alibaba GateWay的网关过滤工厂-CSDN博客
六、Gateway解决跨域问题
6.1 全局解决方案
spring:
cloud:
gateway:
globalcors: # 全局跨域配置
cors-configurations:
'[/**]':
allowedOrigins: "*" # 允许的跨域路径
allowedMethods: # 允许的方法
- GET
- POST
6.2 局部解决方案
spring:
cloud:
gateway:
routes:
- id: my_route
uri: http://localhost:8081
predicates:
- Path=/**
metadata: # 局部跨域配置
cors:
allowedOrigins: '*' # 允许的跨域路径
allowedMethods: # 允许的方法
- GET
- POST
allowedHeaders: '*' # 允许的请求头
maxAge: 30 # 缓存保留时间