SpringCloud Gateway
Posted 司腾
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud Gateway相关的知识,希望对你有一定的参考价值。
使用网关我们会存在什么问题
如果让客户端直接与各个微服务交互,会存在如下问题:
- 存在跨域请求,在一定场景下处理相对复杂
- 身份认证问题,每个微服务需要独立认证
- 某些微服务使用了防火墙或者浏览器不友好的协议,直接访问会有一定困难
网关能给我们解决什么问题
统一接入
- 为各中无线应用提供统一接入服务
- 高性能,高并发,高可用性
- 负载均衡,容灾切换,异地存活
流量管控
- 服务降级
- 熔断
- 路由
安全防护
- 黑白名单
- 风控犯刷,防恶意防刷等
协议适配
- 前端系统(http,https),后端系统(RPC)
- 长,短链接支持
- 路由前端请求,响应结果
GateWay网关介绍
Spring Cloud Gateway 即Spring官方推出的一款API网关,该框架包含了Spring5、SpringBoot2、Project Reactor,其中底层通信框架用的netty。Spring Cloud Gateway在推出之初的时候,Netflix公司已经推出了类似功能的API网关框架ZUUL,但ZUUL有一个缺点是通信方式是阻塞的,虽然后来升级到了非阻塞式的ZUUL2,但是由于Spring Cloud Gateway已经推出一段时间,同时自身也面临资料少、维护性较差的因素没有被广泛应用。
相关术语
Route:
即一套路由规则,是集URI、predicate、filter等属性的一个元数据类。\\
Predicate:
这是Java8函数式编程的一个方法,这里可以看做是满足什么条件的时候,route规则进行生效。
Filter:
filter可以认为是Spring Cloud Gateway最核心的模块,熔断、安全、逻辑执行、网络调用都是filter来完成的,其中又细分为gateway filter和global filter,区别在于是具体一个route规则生效还是所有route规则都生效。
路由规则
Path:
Query:
Method:
Datetime:
RemoteAddr:
Header:
使用动态配置(使用Eureka)
### 过滤器
RewritePathGatewayFilterFactory
PrefixPathGatewayFilterFactory
StripPrefixGatewayFilterFactory
SetPathGatewayFilterFactory
AddRequestParameterGatewayFilterFactory
SetStatusGatewayFilterFactory
自定义过滤器
public class CustomGatewayFilter implements GatewayFilter, Ordered
/**
* 过滤业务逻辑
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
System.out.println("自定义网关过滤器");
return chain.filter(exchange);
/**
* 过滤器执行顺序,数值越小,优先级越高
* @return
*/
@Override
public int getOrder()
return 0;
复制代码
@Configuration
public class GatewayRoutesConfiguration
public RouteLocator routeLocator(RouteLocatorBuilder builder)
return builder.routes().route(r -> (r
//断言 判断条件
.path("/order")
//目标URI
.uri("lb://app-order")
//注册自定义过滤器
.filters(new CustomGatewayFilter())
//路由id,唯一
.id("app-order")
)).build();
复制代码
自定义全局过滤器
@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
System.out.println("自定义全局过滤器");
return chain.filter(exchange);
@Override
public int getOrder()
return 0;
复制代码
源码解析
上图是Spring Cloud Gateway官方文档给出的一个工作原理图,Spring Cloud Gateway 接收到请求后进行路由规则的匹配,然后交给web handler 进行处理,web handler 会执行一系列的filter逻辑。
入口
Gateway的编程模式是webflux+reactor,我对这一块能力有限,能不解释就不解释了(汗) org.springframework.web.reactive.DispatcherHandler#handle
public Mono<Void> handle(ServerWebExchange exchange)
if (this.handlerMappings == null)
return createNotFoundError();
return Flux.fromIterable(this.handlerMappings)
.concatMap(mapping -> mapping.getHandler(exchange))
.next()
.switchIfEmpty(createNotFoundError())
.flatMap(handler -> invokeHandler(exchange, handler))
.flatMap(result -> handleResult(exchange, result));
复制代码
所有webflux的调用都会走这个接口.
这么多实现类,只有这一个是gateway的,就它了.
private Route convertToRoute(RouteDefinition routeDefinition)
//从配置文件中获取predicates
AsyncPredicate<ServerWebExchange> predicate = combinePredicates(routeDefinition);
// 从配置文件中获取filters
List<GatewayFilter> gatewayFilters = getFilters(routeDefinition);
// 封装路由里的内容,返回对象
return Route.async(routeDefinition).asyncPredicate(predicate)
.replaceFilters(gatewayFilters).build();
复制代码
protected Mono<Route> lookupRoute(ServerWebExchange exchange)
return this.routeLocator.getRoutes()
// individually filter routes so that filterWhen error delaying is not a
// 请求进来的接口与路由规则进行匹配
.concatMap(route -> Mono.just(route).filterWhen(r ->
// add the current route we are testing
exchange.getAttributes().put(GATEWAY_PREDICATE_ROUTE_ATTR, r.getId());
return r.getPredicate().apply(exchange);
)
复制代码
一路返回
org.springframework.web.reactive.DispatcherHandler#handle
public Mono<Void> handle(ServerWebExchange exchange)
//从之前放到上下文中取出
Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
//获取对应路由的过滤器
List<GatewayFilter> gatewayFilters = route.getFilters();
//获取全局过滤器
List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
//添加到全局过滤器当中
combined.addAll(gatewayFilters);
// 排序
AnnotationAwareOrderComparator.sort(combined);
if (logger.isDebugEnabled())
logger.debug("Sorted gatewayFilterFactories: " + combined);
//最经典的责任链调用,将每一个全局过滤器都执行一遍
return new DefaultGatewayFilterChain(combined).filter(exchange);
复制代码
请求转发
ForwardRoutingFilter做的事情也很简单,直接复用了spring mvc的能力,将请求提交给dispatcherHandler进行处理,dispatcherHandler会根据path前缀找到需要目标处理器执行逻辑.
响应回写
响应回写的核心类是NettyWriteResponseFilter
结语
只是过了一下大体的流程,细节要根据具体情况再继续分析,对reactor编程方式不是很熟,导致很多地方都只能理解大概,后期会填补这一块的.
以上是关于SpringCloud Gateway的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud系列SpringCloud概述及微服务技术栈的使用