Soul 学习笔记---soul-examples-sofa插件流程分析(十四)

根据soul官方文档的指引,Sofa接入soul网关,启动完 soul-admin,soul-bootdtrap,再去启动 TestSofaApplication 时报连接错误,看了下是因为没启动 zookeeper,zookeeper 开启后 ,就成功运行了 sofa插件,但使用网关访问时报这个错误。

{"code":-106,"message":"Can not find url, please check your configuration!","data":null}

后来发现重启 soul-bootstrap 就可以了,应该是重启才注册了元数据。

sofa插件执行的时候,首先是在 AbstractSoulPlugin 根据 url 找到对应的选择器规则。

在执行 GlobalPlugin 时,使用 DefaultSoulContextBuilder ,构建了 exchange 的数据,从缓存中拿到元数据,放到 exchange 里。

在执行 BodyParamPlugin 插件时,把 sofa 的参数封装在 exchange 里。

exchange.getAttributes().put(Constants.SOFA_PARAMS,
     HttpParamConverter.ofString(() -> serverRequest.uri().getQuery()));
return chain.execute(exchange);

接着在插件链执行到 sofa 插件时,从 exchange拿到元数据。

这里就使用 SofaProxyService 进行泛化调用了,下图中可以看到执行完泛化调用,就拿到返回值了。

拿到返回值后就去执行 SofaResponsePlugin 去对 sofa请求的结果进行处理。

    public Mono<Void> execute(final ServerWebExchange exchange, final SoulPluginChain chain) {
        return chain.execute(exchange).then(Mono.defer(() -> {
            //获取 sofa 请求结果
            final Object result = exchange.getAttribute(Constants.SOFA_RPC_RESULT);
            if (Objects.isNull(result)) {
                Object error = SoulResultWrap.error(SoulResultEnum.SERVICE_RESULT_ERROR.getCode(), SoulResultEnum.SERVICE_RESULT_ERROR.getMsg(), null);
                return WebFluxResultUtils.result(exchange, error);
            }
            //拼接返回值
            Object success = SoulResultWrap.success(SoulResultEnum.SUCCESS.getCode(), SoulResultEnum.SUCCESS.getMsg(), JsonUtils.removeClass(result));
            return WebFluxResultUtils.result(exchange, success);
        }));
    }

今天把 sofa 插件跑通了,也大概看了下执行的流程,在只开启 sofa 插件的情况下,总体来说,使用 GlobalPlugin 放数据,sofaPlugin 处理请求,SofaResponsePlugin 处理返回值。最难懂的就是 泛化调用这一块,这个具体流程明天再研究。

关于 sofa ,其实最终使用的还是 dubbo 的功能,也是一种 rpc 框架,简单在官网了解下它的功能。

  1. 当一个 SOFARPC 的应用启动的时候,如果发现当前应用需要发布 RPC 服务的话,那么 SOFARPC 会将这些服务注册到服务注册中心上。如图中 Service 指向 Registry。
  2. 当引用这个服务的 SOFARPC 应用启动时,会从服务注册中心订阅到相应服务的元数据信息。服务注册中心收到订阅请求后,会将发布方的元数据列表实时推送给服务引用方。如图中 Registry 指向 Reference。
  3. 当服务引用方拿到地址以后,就可以从中选取地址发起调用了。如图中 Reference 指向 Service。
原文地址:https://www.cnblogs.com/fightingting/p/14385287.html