手撕Gateway源码,今日撕工作流程、负载均衡源码

Spring Cloud Gateway源码剖析

通过前面的学习,我们知道SpringCloud Gateway是一个微服务网关,主要实现不同功能服务路由,关于SpringCloud Gateway的实战使用我们就告一段落,我们接下来深入学习SpringCloud Gateway源码。

2.1 Gateway工作流程源码剖析

2.1.1 Gateway工作流程分析

file

前面我们已经学习过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测试如下:
file

当前返回的WebHandler是ExceptionHandlingWebHandler,而ExceptionHandlingWebHandler的delegate是FilteringWebHandler,而FilteringWebHandler的delegate是delegateDispatcherHandler,所有的delegate的handle()方法都会依次执行,我们可以把断点放到DispatcherHandler.handler()方法上:

file

handler()方法会调用所有handlerMappings的getHandler(exchange)方法,而getHandler(exchange)方法会调用getHandlerInternal(exchange)方法:

file

getHandlerInternal(exchange)该方法由各个HandlerMapping自行实现,我们可以观察下断言处理的RoutePredicateHandlerMappinggetHandlerInternal(exchange)方法会调用lookupRoute方法,该方法用于返回对应的路由信息:

file

这里的路由匹配其实就是我们项目中对应路由配置的一个一个服务的信息,这些服务信息可以帮我们找到我们要调用的真实服务:

file

每个Route对象如下:

file

Route的DEBUG数据如下:

file

找到对应Route后会返回指定的FilterWebHandler,如下代码:

file

FilterWebHandler主要包含了所有的过滤器,过滤器按照一定顺序排序,主要是order值,越小越靠前排,过滤器中主要将请求交给指定真实服务处理了,debug测试如下:

file

这里有RouteToRequestUrlFilterForwardRoutingFilter以及LoadBalancerClientFilter等多个过滤器。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值