Soul网关源码分析-dubbo请求如何通过soul转发到后台

在上一篇Soul网关源码分析-dubbo应用启动自动注册拦截规则信息到soul-admin中,我分析了一个接入了soul的dubbo应用,在启动时是如何将服务拦截规则信息注册到soul-admin的,然后这一讲中,计划从源码的角度分析dubbo请求在经过soul转发到后台这个过程中到底做了哪些处理。

按照Soul网关源码分析-请求从浏览器端如何通过soul转发到后台这一讲的分析经验,我认为dubbo的请求转发应该是类似的处理,然而发现按照之前的思路去分析,很快就卡壳了,无法继续往前调试,因为按照之前的经验,只知道SoulWebHandler是入口,然后根据日志输出信息:

2021-01-21 01:22:08.946  INFO 14608 --- [oul-netty-nio-3] o.d.soul.plugin.base.AbstractSoulPlugin  : dubbo selector success match , selector name :/dubbo
2021-01-21 01:22:08.946  INFO 14608 --- [oul-netty-nio-3] o.d.soul.plugin.base.AbstractSoulPlugin  : dubbo selector success match , selector name :/dubbo/insert

能知道会调用AbstractSoulPlugin 这个类,然后其他的信息就无从得知,思考无果后,查阅了其他同学分享的dubbo请求梳理思路,发现有一个很关键的点之前被我忽略了,就是在请求每次到达入口程序SoulWebHandler时,其实都会加载14个插件,并判断这些插件哪些对于当前请求是可用,哪些是不可用或者直接跳过不处理的,这个点非常关键,根据这个思路,我重新在SoulWebHandler这个类的execute方法中打了个断点,跟踪这些插件在dubbo请求中是否有被使用,从而来寻找出处理dubbo请求相关的代码逻辑,以下为跟踪后的结果:
插件分析

列表中标志为跳过的插件可以直接不分析了,可以将焦点定位到没有被跳过的插件,现在开启假设性猜想,从插件的命名来看,跟我们本次分析的dubbo请求直接相关的插件应该就是AlibabaDubblePlugin和DubboResponsePlugin,再结合soul-admin中的插件管理图,可以看到,处于开启状态的插件只有divide和dubbo,而divide由于只针对http请求,也不会生效,因此只剩下dubbo相关的两个插件了,soul-admin中的插件管理图如下图所示:
插件管理
根据上述的分析结果,大胆的在AlibabaDubblePlugin类的doExecute方法中和DubboResponsePlugin类的execute方法中分别打了断点进行调试,经过分析,得出以下分析结果:
1、AlibabaDubblePlugin的doExecute方法主要功能是获取body,soulContext,获得关键的metaData,获取请求的结果,并且放到exchange中,如以下代码所示:

Object result = alibabaDubboProxyService.genericInvoker(body, metaData)

2、DubboResponsePlugin的execute方法主要功能是获取结果result,加工得到success,然后将加工结果返回给客户端,execute方法关键代码如下:

 Object success = SoulResultWrap.success(SoulResultEnum.SUCCESS.getCode(), SoulResultEnum.SUCCESS.getMsg(), JsonUtils.removeClass(result));
	return WebFluxResultUtils.result(exchange, success);

WebFluxResultUtils的result方法代码如下:

public static Mono<Void> result(final ServerWebExchange exchange, final Object result) {
        exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
        return exchange.getResponse().writeWith(Mono.just(exchange.getResponse()
                .bufferFactory().wrap(Objects.requireNonNull(JsonUtils.toJson(result)).getBytes())));
    }

最后,梳理一下分析之后的dubbo请求处理流程,如下图:
dubbo请求处理流程
总结
今天分析dubbo请求处理流程,得到的最大收获是在无法通过结果反推时,先从宏观的层面捋清楚作者在框架设计时的思路,比如我们这次分析的切入点就是得先知道不管是http请求还是dubbo请求,在进入请求入口SoulWebHandler时,都会遍历相同的插件链,区别只是在于针对不同的请求,插件链中某些插件是生效的,某些是不生效的,当流程捋清楚后,调试代码时遇到的问题就会迎刃而解。


参考资料

Soul 网关源码阅读(四)Dubbo请求概览

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页