Spring Cloud Gateway源码剖析
通过前面的学习,我们知道SpringCloud Gateway是一个微服务网关,主要实现不同功能服务路由,关于SpringCloud Gateway的实战使用我们就告一段落,我们接下来深入学习SpringCloud Gateway源码。
2.1 Gateway工作流程源码剖析
2.1.1 Gateway工作流程分析
前面我们已经学习过Gateway的工作流程,如上工作流程图,我们回顾一下工作流程:
1:所有都将由ReactorHttpHandlerAdapter.apply()方法拦截处理,此时会封装请求对象和响应对象,并传递到HttpWebHandlerAdapter.handle()方法。
2:HttpWebHandlerAdapter.handle(),将request和response封装成上下文对象ServerWebExchange,方法通过getDelegate()获取全局异常处理器ExceptionHandlingWebHandler执行全局异常处理
3:ExceptionHandlingWebHandler执行完成后,调用DispatcherHandler.handle(),循环所有handlerMappings查找处理当前请求的Handler
4:找到Handler后调用DispatcherHandler.invokeHandler()执行找到的Handler,此时会调用FilteringWebHandler.handle()
5:DefaultGatewayFilterChain.filter()是关键流程,所有过滤器都会在这里执行,比如服务查找、负载均衡、远程调用等,都在这一块。
上面工作流程我们都是基于说的层面,接下来我们一层一层分析Gateway源码,深入学习Gateway。
2.1.2 Gateway工作流程源码
我们首先来看一下Gateway拦截处理所有请求的方法handle():
/****
*处理所有请求
****/
@Override
public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
if (this.forwardedHeaderTransformer != null) {
request = this.forwardedHeaderTransformer.apply(request);
}
//创建网关上下文对象
ServerWebExchange exchange = createExchange(request, response);
LogFormatUtils.traceDebug(logger, traceOn ->
exchange.getLogPrefix() + formatRequest(exchange.getRequest()) +
(traceOn ? ", headers=" + formatHeaders(exchange.getRequest().getHeaders()) : ""));
//getDelegate()获取当前的Handler
return getDelegate().handle(exchange)
.doOnSuccess(aVoid -> logResponse(exchange))
.onErrorResume(ex -> handleUnresolvedError(exchange, ex))
.then(Mono.defer(response::setComplete));
}
上面getDelegate()方法源码如下:
/**
* Return the wrapped delegate.
* 返回WebHandler:处理web请求的对象
*/
public WebHandler getDelegate() {
return this.delegate;
}
我们进行Debug测试如下:
当前返回的WebHandler是ExceptionHandlingWebHandler
,而ExceptionHandlingWebHandler
的delegate是FilteringWebHandler
,而FilteringWebHandler
的delegate是delegate
是DispatcherHandler
,所有的delegate的handle()
方法都会依次执行,我们可以把断点放到DispatcherHandler.handler()
方法上:
handler()方法会调用所有handlerMappings的getHandler(exchange)
方法,而getHandler(exchange)
方法会调用getHandlerInternal(exchange)
方法:
getHandlerInternal(exchange)
该方法由各个HandlerMapping
自行实现,我们可以观察下断言处理的RoutePredicateHandlerMapping
的getHandlerInternal(exchange)
方法会调用lookupRoute方法,该方法用于返回对应的路由信息:
这里的路由匹配其实就是我们项目中对应路由配置的一个一个服务的信息,这些服务信息可以帮我们找到我们要调用的真实服务:
每个Route对象如下:
Route的DEBUG数据如下:
找到对应Route后会返回指定的FilterWebHandler,如下代码:
FilterWebHandler主要包含了所有的过滤器,过滤器按照一定顺序排序,主要是order值,越小越靠前排,过滤器中主要将请求交给指定真实服务处理了,debug测试如下:
这里有RouteToRequestUrlFilter
和ForwardRoutingFilter
以及LoadBalancerClientFilter
等多个过滤器。