关于Spring Cloud Gateway的使用
1 Gateway介绍
1.1 基本介绍
- Gateway是在spring生态系统上构建的API网关服务,基于Spring5,SpringBoot2 和 Project Reactor等技术
- Gateway提供亦庄简单而有效的方式来对API进行路由,以及提供一些强大的过滤能力,例如:熔断、限流、重试等
- Gateway使用的Webflux种的reactor-netty响应式编程组件,底层使用了Netty
1.2 功能
- 反向代理
- 鉴权
- 流量控制
- 熔断
- 日志监控
1.3 使用位置
1.4 选择gateway原因
- (1)zuul1.0进入了维护阶段,而Gateway是SpringCloud团队研发的,是亲儿子产品
- (2)Gateway是基于
异步非阻塞模型上进行开发的
,性能方面不需要担心 - (3)Netflix虽然发布最新的Zuul2.x,但没有与SpringCloud整合的计划
2 三大核心概念
2.1 Route(路由)
- 路由是构建网关的基本模块,它有ID,目标URI,一系列的断言和过滤器组成,如果断言为true,则匹配该路由
2.2 Predicate(断言)
- 断言表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真,可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言
- 开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
2.3 Filter(过滤)
- 使用过滤器,可以在请求被路由前或者之后对请求进行修改
2.4 总结
- web请求,通过一些匹配条件,定位到真正的服务器。并在这个转发过程的前后,进行一些精细化控制。
- predicate就是我们的匹配条件
- filter,就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标uri,就可以实现一个具体的路由
3 Gateway工作流程
- 路由转发+执行过滤器链
4 Gateway配置
4.1 服务搭建
- (1)新建Module
cloud-gateway-gatway9527
- (2)修改POM(引入依赖)
1
2
3
4
5
6
7
8
9
10<!-- eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
- (3)修改配置文件yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14server:
port: 9527
spring:
application:
name: cloud-gateway #服务器名称
eureka:
instance:
hostname: cloud-gateway-service #eureka上主机别名
client:
register-with-eureka: true
fetch-registry: true
defaultZone: http://eurka7001.com:7001/eureka
- (4)主启动类
1
2
3
4
5
6
7
//注册到eureka服务中心
public class GatewayMain9527 {
public static void main(String[] args) {
SpringApplication.run(GatewayMain9527.class, args);
}
}
4,2 网关配置
- (1)修改yaml配置
1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: payment-route # 路由ID,名字随意(建议配合服务名)
uri: http://localhost:8001 #断言匹配成功后,转发的路由地址
predicates:
- Path=/payment/get/** # 断言。路径相匹配的进行路由转发,注意Path是大写开头
- (2)测试
- 启动eurka服务注册中心,启动服务器,再启动网关
5 通过编码形式配置网关
1 |
|
6 微服务名实现动态路由
6.1 路由访问变化
- 添加网关前:
- 使用网关
- 但是上面的网关配置是将转发路由写死的,打不到负载均衡,所以需要动态路由实现负载均衡
6.2 配置动态路由
修改yaml配置文件
1
2
3
4
5
6
7
8
9
10
11spring:
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由转发
routes:
- id: payment-route # 路由ID,名字随意(建议配合服务名)
uri: lb://cloud-payment-service #lb:loadBalance负载均衡,从服务注册中心获取对应服务名的服务器
predicates:
- Path=/payment/lb/** # 断言。路径相匹配的进行路由转发,注意Path是大写开头测试:
- 开启eureka7001, payment8001, payment8002,gateway9527调用接口测试
7 Predicates断言使用
7.1 断言类型
7.2 After
- 后面跟指定时间,当当前时间在指定时间之后,此路径访问才生效
- 使用场景:提前上架服务器,但不允许服务器被访问(游戏开服)
- 时间格式:可以通过代码来获取时间格式
1
2
3
4ZonedDateTime now = ZonedDateTime.now();
System.out.println(now);
//2021-03-13T16:47:32.605+08:00[Asia/Shanghai]
//日期 T 时间 xxxx[xx/xx]
7.3 Before
- 在指定时间之前,路径访问才生效,和After相反
7.4 Between
- 在两个指定之间之内,路径访问才生效,参数为两个时间,就比前面多一个时间参数
7.5 Cookie
- Cookie Route Predicate需要两个参数,一个是Cookie name,一个是正则表达式
- 路由规则会通过获取对应的Cookie name值(key)和正则表达式(value)去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行
1 | - Cookie=username, letere //要cookies要带上"username=letere"参数 |
7.6 Header
- 请求头和Cookie样,两个参数,kv键值对
- 带有此kv键值对就匹配成功,进行路由转发
8 Filter过滤器使用
8.1 Filter介绍
- 路由过滤器可用于修改进入HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用
- Spring Cloud Gateway内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生
8.2 Filter分类
- 生命周期
pre
post
- 种类
- GatewayFilter:单一过滤器
- GlobalFilter:全局过滤器
8.3 自定义过滤器
- (1)实现
GlobalFilter
和Ordered接口
- (2)重写里面的方法
- 例子:配置一个过滤器,请求参数必须要带”uname”才放行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class LogGatewayFilter implements GlobalFilter, Ordered {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("******** come from LogGatewayFilter:" + new Date());
String uname = exchange.getRequest() //获取请求
.getQueryParams() //获取查询参数
.getFirst("uname"); //获取对应参数值
if(uname == null) {
log.info("********用户名为null,非法用户,o(╥﹏╥)o");
exchange.getResponse() //获取响应
.setStatusCode(HttpStatus.NOT_ACCEPTABLE); //响应会状态码
return exchange.getResponse().setComplete(); //拦截返回信息
}
return chain.filter(exchange); //放行
}
public int getOrder() { //过滤器执行顺序,越小优先级越高
return 0;
}
}