文章目录
前言
本文为学习Gateway后的学习总结记录,大致包含包含以下部分:
- Gateway的服务搭建
- Gateway的各种Filter
- Gateway解决跨域问题
一、GateWay引言
- 为什么需要网关呢?这里直接介绍网关的功能:
- 身份认证和权限校验
- 服务路由与负载均衡
- 请求限流
- 在SpringCloud中的网关的实现包括两种:
gateway
和zuul
。zuul 是基于Servlet实现的,属于阻塞式编程。而SpringCloudGateway 则属于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。
二、搭建网关服务
1. 导入相关依赖
网关也属于一种服务,同样需要在nacos中完成注册。
```xml
<!-- nacos客户端发现依赖-->
</dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 网关gateway依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
```
2. 网关路由相关配置
网关路由可以配置的内容包括:
-
路由id: 路由唯一标识。
-
uri: 路由目的地,支持lb和http 两种形式。(lb 表示向nacos查询地址信息)
-
predicates: 路由断言。用来判断请求是否符合要求,符合才进行路由转发。
-
filter: 路由过滤器,处理请求或响应。
例如:
spring: gateway: routes: - id: user-service # 路由标识,必须唯一 uri: lb://userservice predicates: # 路由断言,判断请求是否符合规则 - Path=/user/** # 路径断言,查看请求的路径是否满足 /user开头 - After=2031-04-13T15:14:47.433+08:00 ... # 在这个时间段之后才能访问 - Before=2031-04-13T15:14:47.433+08:00 ... # 在这个时间段之前才能访问
将predicates称为路由断言工厂(Route Predicate Factory), Spring 中提供了11种基本的Predicate工厂:
3. 统一网关GatewayFilter
GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理,例如:添加请求头信息等。
这里称filter为路由过滤器工厂(Route Filter Factory), Spring提供了31种不同的路由过滤器工厂:
例如:给所有进入userservice的请求添加一个请求头:
spring:
gateway:
routes:
- id: user-service # 路由标识,必须唯一
uri: lb://userservice
predicates: # 路由断言,判断请求是否符合规则
- Path=/user/** # 路径断言,查看请求的路径是否满足 /user开头
- After=2031-04-13T15:14:47.433+08:00 ... # 在这个时间段之后才能访问
- Before=2031-04-13T15:14:47.433+08:00 ... # 在这个时间段之前才能访问
filters:
- AddRequestHeader=Truth,hahaha # 为指定服务配置过滤器
如果需要给所有服务都添加过滤器,这里也可以设置默认过滤器:
spring:
gateway:
routes:
- id: user-service # 路由标识,必须唯一
uri: lb://userservice
predicates: # 路由断言,判断请求是否符合规则
- Path=/user/** # 路径断言,查看请求的路径是否满足 /user开头
- After=2031-04-13T15:14:47.433+08:00 ... # 在这个时间段之后才能访问
- Before=2031-04-13T15:14:47.433+08:00 ... # 在这个时间段之前才能访问
filters:
- AddRequestHeader=Truth,hahaha # 为指定服务配置过滤器
default-filters: # 配置所有服务的过滤器
- AddRequestHeader=Truth,hahaha
4. 全局过滤器GlobalFilter
全局过滤器的作用与默认过滤器一样,区别在于默认过滤器通过配置文件定义,处理逻辑是固定的;而全局过滤器的逻辑是通过代码实现的。定义的方式是实现GlobalFilter接口。
/*
自定义Glocal-Filter
*/
@Order() // 定义过滤器的执行顺序,数值越小,优先级越高。(-1表示优先级最高)
@Component
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1. 获取请求参数
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String, String> params = request.getQueryParams();
// 2. 获取参数中的authorization参数
String auth = params.getFirst("authorization");
// 3. 判断是否为admin
if("admin".equals(auth)){
// 放行
return chain.filter(exchange);
}
// 4. 拦截
// 设置状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
// 拦截响应
return exchange.getResponse().setComplete();
}
}
此时,请求进入网关后,会碰到三类过滤器:默认过滤器、路由过滤器和全局过滤器。
过滤器执行顺序:
-
每一个过滤器都必须指定一个Int 类型的order值,order值越小,优先级越高,执行顺序越靠前。
-
GlobalFiletr 可以通过实现Order接口,或者添加@Order注解来指定order值。
-
路由过滤器和默认过滤器的order由Spring 指定,默认按照声明顺序从1递增。
-
当过滤器的order值相同时,会按照 默认过滤器 > 路由过滤器 > 全局过滤器的顺序执行。
三、Gateway解决跨域问题
跨域: 域名不一致就是跨域,主要包括:域名不同、域名相同端口不同。
跨域问题: 浏览器会默认禁止请求的发起者与服务端发生跨域Ajax 请求,请求被浏览器拦截。
解决方案: CORS。传统解决的思路大概可以概括为:浏览器接受到跨域请求时,会向服务端发起一次询问,询问是否放行。
网关处理跨域问题同样采用CORS方案,只需要简单的配置即可:
spring:
cloud:
gateway
globalcors: # 全局跨域处理
add-to-simple-url-handler-mapping: true # 解决options请求被拦截的问题
cors-configurations:
'[/**]': # 对所有请求做处理
allowedOrigins: # 允许哪些网站的跨域请求
- "http://localhost:8090"
- "http://www.leyou.com"
allowedMethods: # 允许苦于ajax的请求方式
- "GET"
- "POST"
- "PUT"
- "DELETE"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
allowCredentials: true # 是否允许携带cookie
maxAge: 360000 # 此次跨域检测的有效期
以上就为本篇文章的全部内容啦!
如果本篇内容对您有帮助的话,请多多点赞支持一下呗!