美文网首页
soul网关学习8-dubbo协议转换3

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

作者: niuxin | 来源:发表于2021-01-22 00:26 被阅读0次

    继续上篇分析,这里只分析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 ...

    相关文章

      网友评论

          本文标题:soul网关学习8-dubbo协议转换3

          本文链接:https://www.haomeiwen.com/subject/nftdzktx.html