dubbo服务暴露原理解析

配置解析

dubbo 的各个配置项,详细的可以参考官网
只有 group,interface,version 是服务的匹配条件,三者决定是不是同一个服务,其它配置项均为调优和治理参数
所有的配置最终都转为URL,由服务提供方生成,经由注册中心传给消费者
每个配置元素都会有对应的配置类

  • dubbo:application 用于配置应用信息,主要是用于服务治理的, 只有其中的compiler和logger用于性能调优, compiler用于配置动态编译器, logger用于配置日志输出方法
  • dubbo:registry 用于配置注册中心, 如果有多个注册中心,则使用多个标签声明, 并且在dubbo:service 和dubbo:reference 中 的register属性中指定对应的注册 中心
  • dubbo:provider 服务提供者缺省配置,为dubbo:protocol和dubbo:service缺省值配置
  • dubbo:service 服务提供者暴露服务配置, 有几个服务要暴露就配置几个
  • dubbo:protocol 服务提供者配置,如果需要支持多协议,可以声明多个标签, 并且在dubbo:service中的protocol属性指定使用哪个协议
  • dubbo:reference 服务消费者引用服务配置,
  • dubbo:consumer 服务消费者缺省值配置, 同时为dubbo:reference的缺省值配置
  • dubbo:method 方法 级配置, 为dubbo:service 和dubbo:reference的子标签, 用于控制到方法级

不同粒度的覆盖关系

  • 方法级别优先,接口次之, 全局再次之
  • 如果级别一样,消费方优先,提供方次之, 其中提供方的配置通过URL,经由注册中心传给消费者

外部化配置
外部化配置 即是将配置放到配置中心,比如如 Apollo, Nacos
外部化配置相对本地配置有更高的优先级, 可以通过 -Ddubbo.config-center.highest-priority=false 调整

dubbo 支持四种配置来源,按配置的优先级从高到低分别是

  • JVM参数配置
  • 外部化配置
  • ServiceConfig、ReferenceConfig 等编程接口采集的配置,比如XML配置等
  • 本地配置文件 dubbo.properties

解析服务的实现原理

dubbo 使用spring框架提供的功能,将XML配置文件解析为bean

  1. spring应用启动时,会调用DefaultBeanDefinitionDocumentReader.parseBeanDefinitions 方法解析xml 标签, 根据每个标签的命名空间决定如何解析该标签
// DefaultBeanDefinitionDocumentReader类

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
   
        if (delegate.isDefaultNamespace(root)) {
   
        // xml 文件的根元素设了默认的命名空间 xmlns = "http://www.springframework.org/schema/beans"
            NodeList nl = root.getChildNodes();

            for(int i = 0; i < nl.getLength(); ++i) {
   
                Node node = nl.item(i);
                if (node instanceof Element) {
   
                    Element ele = (Element)node;
                    if (delegate.isDefaultNamespace(ele)) {
   
                    // 如果是默认的命名空间
                        this.parseDefaultElement(ele, delegate);
                    } else {
   
                    // <dubbo:xxxx> 会走该分支
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        } else {
   
            delegate.parseCustomElement(root);
        }

    }
  1. BeanDefinitionParserDelegate 会获取该标签的命名空间, NamespaceHandlerResolver根据命名空间返回对应的命名空间处理器. NamespaceHandlerResolver只有一个默认实现 DefaultNamespaceHandlerResolver, 它会去加载 META-INF/spring.handlers 文件
    dubbo.jar定义了该文件,内容为
    http://dubbo.apache.org/schema/dubbo=org.apache.dubbo.config.spring.schema.DubboNamespaceHandler
    http://code.alibabatech.com/schema/dubbo=org.apache.dubbo.config.spring.schema.DubboNamespaceHandler
    所以,返回的handler为 DubboNamespaceHandler, 然后用这个handler去解析该标签

// BeanDefinitionParserDelegate类
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
   
        String namespaceUri = this.getNamespaceURI(ele);
        if (namespaceUri == null) {
   
            return null;
        } else {
   
            NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
            if (handler == null) {
   
                this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
                return null;
            } else {
   
                return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
            }
        }
    }

在DubboNamespaceHandler的init 方法会设置每个标签的解析器

public void init() {
   
        registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
        registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
        registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
        registerBeanDefinitionParser("config-center", new DubboBeanDefinitionParser(ConfigCenterBean.class, true));
        registerBeanDefinitionParser("metadata-report", new DubboBeanDefinitionParser(MetadataReportConfig.class, true));
        registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
        registerBeanDefinitionParser("metrics", new DubboBeanDefinitionParser(MetricsConfig
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值