soul网关学习8-dubbo协议转换3

2021-01-22  本文已影响0人  niuxin

继续上篇分析,这里只分析dubbo插件是如何处理配置数据的。

dubbo插件配置数据处理器

  1. 回到源码org.dromara.soul.plugin.alibaba.dubbo.handler.AlibabaDubboPluginDataHandler
    AlibabaDubboPluginDataHandler
  2. 从上图可以看到AlibabaDubboPluginDataHandler只会处理plugin的配置,对于selectorrule的配置是不进行进行任何处理的【需纠正一下:这里不是说selectorrule的配置对于dubbo插件来说是无意义的,只是AlibabaDubboPluginDataHandler不处理。真正处理selectorrule的逻辑就是在CommonPluginDataSubscribersubscribeDataHandler方法中完成的;因为对于不同插件其处理逻辑大致相同,因此只有极个别的插件需要重写handlerSelectorhandlerRule方法】。那dubbo插件中的配置是如何能被正确dubbo服务的请求路径给到soul-bootstrap做路由的呢?
  3. 我们知道dubbo服务注册时,会生成对应的元数据,于是点击元数据的同步,看下bootstrap会有什么反应
    meta_data_sync
  4. 元数据的配置在soul-bootstrap端的处理逻辑则由org.dromara.soul.plugin.sync.data.weboscket.handler.MetaDataHandler决定
    WebsocketDataHandler
  5. 看下具体的处理逻辑是怎样的


    MetaDataHandler
  6. 我们先看看MetaDataSubscriber的类继承结构
    MetaDataSubscriber-implements
  7. 从上图基本可以看出对于每种特定的微服务框架都有一个handler与之对应,这里我们只关注org.dromara.soul.plugin.alibaba.dubbo.subscriber.AlibabaDubboMetaDataSubscriber。打断点进入发现,这里的处理大致如下:所有dubbo服务的接口,都会放到org.dromara.soul.plugin.alibaba.dubbo.cache.ApplicationConfigCachecache中,key为dubbo服务声明的path,value则是根据元数据生成的服务引用ReferenceConfig。届时在具体调用的时候,则能根据请求的url找到ReferenceConfig,再根据其生成相应的 Invoker,从而完成http请求转换为dubbo服务的请求
    public void onSubscribe(final MetaData metaData) {
        // 只是把跟dubbo相关的元数据存放到内存中
        if (RpcTypeEnum.DUBBO.getName().equals(metaData.getRpcType())) {
            MetaData exist = META_DATA.get(metaData.getPath());
            // 如果当前的dubbo路径不存在,则需要初始化服务引用
            if (Objects.isNull(META_DATA.get(metaData.getPath())) || Objects.isNull(ApplicationConfigCache.getInstance().get(metaData.getPath()))) {
                // The first initialization
                // 将服务路径与服务引用配置放到应用配置缓存中
                ApplicationConfigCache.getInstance().initRef(metaData);
            } else {
                // There are updates, which only support the update of four properties of serviceName rpcExt parameterTypes methodName,
                // because these four properties will affect the call of Dubbo;
                // 如果存在,则查看是否存在属性变更的地方,如果存在则要重新build的服务引用
                if (!Objects.equals(metaData.getServiceName(), exist.getServiceName())
                        || !Objects.equals(metaData.getRpcExt(), exist.getRpcExt())
                        || !Objects.equals(metaData.getParameterTypes(), exist.getParameterTypes())
                        || !Objects.equals(metaData.getMethodName(), exist.getMethodName())) {
                    // 重新构建服务引用并放到应用配置缓存中
                    ApplicationConfigCache.getInstance().build(metaData);
                }
            }
            META_DATA.put(metaData.getPath(), metaData);
        }
    }
  1. 看下元数据MetaData生成引用服务配置ReferenceConfig的逻辑
    public ReferenceConfig<GenericService> build(final MetaData metaData) {
        ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
        reference.setGeneric(true);
        reference.setApplication(applicationConfig);
        reference.setRegistry(registryConfig);
        reference.setInterface(metaData.getServiceName());
        reference.setProtocol("dubbo");
        String rpcExt = metaData.getRpcExt();
        DubboParamExtInfo dubboParamExtInfo = GsonUtils.getInstance().fromJson(rpcExt, DubboParamExtInfo.class);
        if (Objects.nonNull(dubboParamExtInfo)) {
            // 版本
            if (StringUtils.isNoneBlank(dubboParamExtInfo.getVersion())) {
                reference.setVersion(dubboParamExtInfo.getVersion());
            }
            // 分组
            if (StringUtils.isNoneBlank(dubboParamExtInfo.getGroup())) {
                reference.setGroup(dubboParamExtInfo.getGroup());
            }
            // 负载均衡
            if (StringUtils.isNoneBlank(dubboParamExtInfo.getLoadbalance())) {
                final String loadBalance = dubboParamExtInfo.getLoadbalance();
                reference.setLoadbalance(buildLoadBalanceName(loadBalance));
            }
            // url
            if (StringUtils.isNoneBlank(dubboParamExtInfo.getUrl())) {
                reference.setUrl(dubboParamExtInfo.getUrl());
            }
            // 超时
            Optional.ofNullable(dubboParamExtInfo.getTimeout()).ifPresent(reference::setTimeout);
            // 重试
            Optional.ofNullable(dubboParamExtInfo.getRetries()).ifPresent(reference::setRetries);
        }
        try {
            Object obj = reference.get();
            if (obj != null) {
                log.info("init alibaba dubbo reference success there meteData is :{}", metaData.toString());
                // 将请求路径与dubbo服务引入放入应用配置的cache中
                cache.put(metaData.getPath(), reference);
            }
        } catch (Exception e) {
            log.error("init alibaba dubbo refernce ex:{}", e.getMessage());
        }

        return reference;
    }

To be continued ...

上一篇下一篇

猜你喜欢

热点阅读