1.1 简介
1.1.1 概述
Spring Cloud Gateway 是 Spring Cloud 体系的第二代网关组件,基于 Spring 5.0 的新特性 WebFlux 进行开发,底层网络通信框架使用的是 Netty,所以其吞吐量高、性能强劲,取代了第一代的网关组件 Zuul。Spring Cloud Gateway 组件的核心是一系列的过滤器,通过这些过滤器可以将客户端发送的请求转发到对应的微服务。Spring Cloud Gateway 是加在整个微服务最前沿的防火墙和代理器,隐藏微服务结点 IP 端口信息,从而加强安全保护。Spring Cloud Gateway 本身也是一个微服务,需要注册到服务注册中心。
1.1.2 核心概念
♞ 路由(route)
路由是网关的基本模块,由一个ID、一个目的URL、一组断言工厂、一组 Filter 组成。如果路由断言为真,说明请求 URL 和配置路由匹配。
♞ 断言(Predicate)
Spring Cloud Gateway 中的断言函数输入类型是 Spring5.0 框架中的 ServerWebExchange。Spring Cloud Gateway 的断言函数允许开发者去定义匹配来自于 Http Request 中的任何信息比如请求头和参数。
♞ 过滤器(Filter)
一个标准的 Spring WebFilter。Spring Cloud Gateway 中的 Filter 分为两种类型的 Filter,分别是 Gateway Filter 和 Global Filter。过滤器 Filter 将会对请求和响应进行修改处理。
1.1.3 相关依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
1.2 基本使用
1.2.1 创建基础工程
1.2.2 Gateway 配置文件
server:
port: 8100
spring:
application:
name: gateway-server # 应用名称,在 Eureka 中作为 id 标识
cloud:
gateway:
routes:
# 路由 id 随便写
- id: info-server
# 服务地址,若使用了注册中心可以使用服务名 lb://info-server,使用 lb 协议时会自动负载均衡
uri: http://127.0.0.1:8200
# 服务路径
predicates:
- Path=/info/**
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8000/eureka
server:
enable-self-preservation: false # 关闭自我保护模式, 默认为打开
eviction-interval-timer-in-ms: 5000 # 续期时间,即扫描失效服务的间隔时间
1.2.3 Gateway 启动类
/**
* Created with IntelliJ IDEA.
*
* @author Demo_Null
* @date 2020/11/10
* @description
*/
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
1.2.4 请求服务
启动服务后,我们发现不论是直接使用 http://127.0.0.1:8200/info/get
请求服务,还是通过网关 http://127.0.0.1:8100/info/get
请求服务都没有问题。注意 Gateway 默认时全路径转发的。
1.2.5 其他配置
spring:
cloud:
gateway:
discovery:
locator:
# 使用服务发现路由,即直接使用注册中心路由配置
enabled: true
# 服务路由名小写
lower-case-service-id: true
routes:
# 路由 id 随便写
- id: info-server
# 服务地址,若使用了注册中心可以使用服务名 lb://info-server,使用 lb 协议时会自动负载均衡
uri: http://127.0.0.1:8200
# 路由断言,可配置映射路径
predicates:
- Path=/info/**
# 请求方法
- Method=GET
# 这个路由规则会在 东八区 2020-11-11 11:11:11 后生效
- After=2020-11-11T11:11:11.111+08:00
# 这个路由规则会在 东八区 2020-11-11 11:11:11 前有效
- Before=2020-11-11T11:11:11.111+08:00
# 这个路由规则会在 东八区 2020-11-11 11:11:11 到 2021-11-11 11:11:11 之间有效
- Between=2020-11-11T11:11:11.111+08:00, 2021-11-11T11:11:11.111+08:00
filters:
# 添加请求路径的前缀,转发路径会添加以下前缀 /info/get ☞ /gateway/info/get
- PrefixPath=/gateway
# 过滤路径,1 表示过滤 1个,2 表示过滤 2个,以此类推,转发时会去掉前缀 /info/get ☞ /get
- StripPrefix=1
1.3 过滤器
1.3.1 概述
Gateway 作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作往往是通过网关提供的过滤器来实现的。路由前缀的功能也是使用过滤器实现的,有以下几种常见自带过滤器。☞ 官方文档
过滤器名 | 描述 |
---|---|
AddRequestHeader | 对匹配上的请求加上 Header |
AddResponseHeader | 对从网关返回的响应添加 Header |
AddRequestParameters | 对匹配上的请求路由添加参数 |
StripPrefix | 对匹配上的请求路径去除前缀 |
1.3.2 配置全局默认过滤器
spring:
cloud:
gateway:
routes:
filters:
# 对匹配的请求,会额外添加 X-Request-MyName:Bar 的 header
- AddRequestHeader=X-Request-MyName, Bar
# 对匹配的请求,响应返回时会额外添加 X-Response-MyName:Bar 的 header 返回
- AddResponseHeader=X-Response-MyName, Bar
# 对匹配的请求,会额外添加 name=bar 的请求参数
- AddRequestParameter=name, bar
1.3.3 自定义过滤器
1.4 其他配置
1.4.1 负载均衡和熔断
Gateway 中默认就已经集成了 Ribbon 负载均衡和 Hystrix 熔断机制。但是默认的策略可能不符合我们的要求,所以我们可以直接使用 Ribbon 和 Hystrix 的配置修改默认值。
hystrix:
command:
default:
execution:
isolation:
thread:
# 熔断超时设置,默认为 1秒
timeoutInMilliseconds: 2000
ribbon:
# 建立连接所用时间,适用于网络正常的情况下,两端连接所用的时间
ConnectTimeout: 5000
# 建立连接后从服务器读取到可用资源所用的时间
ReadTimeout: 5000
1.4.2 Gateway 跨域
一般网关都是所有微服务的统一入口,必然在被调用的时候会出现跨域问题。在访问 Spring Cloud Gateway 网关服务器的时候,出现跨域问题的话;可以在网关服务器中通过配置解决,允许哪些服务是可以跨域请求的;具体配置如下:
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
# 允许携带认证信息
allow-credentials: true
# 允许跨域的源(网站域名/ip),设置 * 为全部
allowed-origins:
- "http://localhost:8100"
- "http://localhost:8200"
# 允许跨域请求里的 head 字段,设置 * 为全部
allowed-headers: "*"
# 允许跨域的 method, 默认为 GET 和 OPTIONS,设置 * 为全部
allowed-methods:
- OPTIONS
- GET
- POST
# 跨域允许的有效期
max-age: 3600
若以上配置不生效可以手动配置 Cors,基本上就可以解决跨域问题了。
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedMethod("*");
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}