文章目录

  • 概述
  • dubbo调用过程
  • sofa调用过程
  • 总结


概述

由于dubbo及sofa都属于rpc框架,都有自己的注册服务中心以及自己进行远程调用时的相关协议规定,因此放到一块进行对比分析

dubbo调用过程

本调用过程主要以apache-dubbo进行讲解。

  1. 请求过来之后,首先会调用dubbo独有的BodyParamPlugin该插件,主要作用为组装dubbo调用时所需要的参数(普通url参数或者json或者表单格式),将该数据存储到ServerWebExchange中,并进行下一调用链调用
  2. 紧接着会进入ApacheDubboPlugin插件中,该插件为真正的执行调用dubbo服务,调用最核心的方法为:
final Mono<Object> result = dubboProxyService.genericInvoker(body, metaData, exchange);

其中body为步骤1拼装的参数,metaData存储了zookeeper地址等信息,该方法为dubbo的泛化调用,具体分析如下:

thrift dubbo 比较 dubbo和sofa_返回结果


标红色1部分为真正的调用dubbo服务(dubbo的泛化调用机制暂时没有进行深入研究,等后续有机会再补上),红色2部分是往上下文中放入dubbo的返回结果,紧接着进入下一个插件调DubboResponsePlugin

  1. DubboResponsePlugin也是dubbo独有的插件,该插件的核心源码如下:

    其主要作用是将dubbo调用返回的结果进行转换成soul结果格式,然后将结果返回给客户端。
    dubbo整个插件的调用过程大致如上所述。alibaba-dubbo与appche-dubbo的调用过程几乎一致,不再分析

sofa调用过程

sofa的调用过程与dubbo非常相似,同样也分了参数插件处理(BodyParamPlugin),真正调用插件(SofaPlugin),以及返回结果插件处理(SofaResponsePlugin),其中BodyParamPlugin和SofaResponsePlugin和dubbo几乎一致,不再具体分析,现在主要看看SofaPlugin插件是如何调用处理的,与duubo一样,sofa的远程调用核心代码如下:

final Mono<Object> result = sofaProxyService.genericInvoker(body, metaData, exchange);

进入该方法中

public Mono<Object> genericInvoker(final String body, final MetaData metaData, final ServerWebExchange exchange) throws SoulException {
        //省略部分代码
       //该代码是对传入的参数进行处理
        if (null == body || "".equals(body) || "{}".equals(body) || "null".equals(body)) {
            pair = new ImmutablePair<>(new String[]{}, new Object[]{});
        } else {
            pair = sofaParamResolveService.buildParameter(body, metaData.getParameterTypes());
        }
        //省略中间代码
        //以下为真正的发起调用,也是sofa的泛化调用
        genericService.$genericInvoke(metaData.getMethodName(), pair.getLeft(), pair.getRight());
        return Mono.fromFuture(future.thenApply(ret -> {
            if (Objects.isNull(ret)) {
                ret = Constants.SOFA_RPC_RESULT_EMPTY;
            }

            GenericObject genericObject = (GenericObject) ret;
            exchange.getAttributes().put(Constants.SOFA_RPC_RESULT, genericObject.getFields());
            exchange.getAttributes().put(Constants.CLIENT_RESPONSE_RESULT_TYPE, ResultEnum.SUCCESS.getName());
            return ret;
        })).onErrorMap(SoulException::new);
    }

与dubbo调用相比,基本过程类似,两者调用的时候,官方都提供了泛化调用等相关接口,按照规定格式调用即可,不同的是,两者对请求参数的包装不一样,需要单独做处理

总结

dubbo和sofa都属于rpc调用框架,经过分析两者调用逻辑几乎一致,都是经过三个步骤:

  1. 对请求参数的处理
  2. 发起真正的服务调用
  3. 对调用返回的结果进行去除相关特性的处理,统一为soul格式的结果
    因此,如果有接入有新的rpc框架,都可以按照上述逻辑进行处理