统一网关Geteway
目录
1. 为什么需要网关
网关功能:限制对外访问,一切请求先通过网关
- 身份认证和权限校验
- 服务路由、负载均衡
- 请求限流
在SpringCloud中网关的实现包括两种:
- getaway:基于Spring5中提供的WebFlux,属于响应式编程
- zuul:基于Servlet的实现,属于阻塞式编程
2. geteway快速入门
搭建网关服务
- 创建新的module,引入SpringCloudGateway依赖和nacos服务发现依赖(不分先后)
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
- 编写路由配置及nacos地址
server:
port: 10010 # 网关端口
spring:
application:
name: geteway # 服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
geteway:
routes: # 网关路由配置
# 多个路由
- id: user-service # 路由id数组
uri: lb://uservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,判断请求是否符合路由规则
- Path=/user/** # 按照路径匹配,只要以/user/开头就是符合
- id: xxx-service
uri: lb://xxx
predicates:
- Path=/xxx/**
3. 断言工厂 Route Predicate Factory
解析断言规则字符串 Path=/xxx/
org.springframework.cloud.geteway.handler.predicate.PathRoutePredicateFactory
4. 过滤工厂 GatewayFilterFactory
可以对进入网关的请求和微服务返回的响应做处理
# gateway application.yml
spring:
cloud:
getaway:
routes: # 网关路由配置
- id: xxx-service
uri: lb://xxx
predicates:
- Path=/xxx/**
filters: # 单个配置
- AddRequestHeader=Truth,Hello World! # Truth 参数名称 , 表示等于
default-filters: # 全局配置,与 routes 同级
- AddRequestHeader=Truth,Hello World!
5. 全局过滤器 GlobalFilter
处理一切进入网关的请求和微服务响应,进行逻辑处理。
/**
* 处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
* @param exchange 请求上下文,可以获取Request、Response等信息
* @param chain 把请求委托给下一个过滤器
* @return {#vode Mono<Void>} 返回表示当前过滤器业务结束
*/
public interface GlobalFilter{
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}
@Order(-1) // 顺序注解 值越小,优先级越高
@Component
public class AuthorzeFilter implements GlobalFilter{
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){
// 1.获取请求参数
ServerHttpRequest request = exchange.getRequest();
MultiValusMap<String, String> params = request.getQueryParams;
// 2.获取参数中的 authorzation 参数
String auth = params.getFirst("authorzation");
// 3.判断
if ( "admin".equals(auth) ){
// 4.通过
return chain.filter(exchange);
}
// 5.拦截
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
}
// 接口式
@Component
public class AuthorzeFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){
// 1.获取请求参数
ServerHttpRequest request = exchange.getRequest();
MultiValusMap<String, String> params = request.getQueryParams;
// 2.获取参数中的 authorzation 参数
String auth = params.getFirst("authorzation");
// 3.判断
if ( "admin".equals(auth) ){
// 4.通过
return chain.filter(exchange);
}
// 5.拦截
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
@Override
public int getOrder(){
return -1;
}
}
过滤器执行顺序
请求进入网关后会碰到三类过滤器:
当前路由过滤器、DefaultFilter、GlobalFilter
6. 跨域问题
- 域名不同
- 域名相同,端口不同
浏览器禁止请求的发起者与服务端发生跨域ajax请求
解决:CORS方案
# gateway application.yml
spring:
cloud:
gateway:
globalcors:
add-to-simple-url-handler-mapping: true
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求
- "http://localhos:8080"
- "http://localhos:8081"
allowedMethods: # 允许的跨域ajax的请求方式
- "GET"
- "POST"
allowedHeaders: "*" # 允许在请求中携带头信息
allowedCredentials: true # 是否允许携带cookie
maxAge: 360000 # 这次跨域检测的有效期
最后
以上是学习 黑马程序员《微服务技术全栈教程》的学习笔记