Dubbo点滴(3)之服务配置Servi

发布时间:2019-09-21 11:04:12编辑:auto阅读(1726)


    接触过dubbo的同学,见到下面的配置都非常熟悉了,含义不多说。

    本章主要目的,对DUBBO配置原理进行剖析。

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        ">
         
        <!-- 当前应用信息配置 -->
        <dubbo:application name="demo-provider" />
        
        <!-- 连接注册中心配置 -->
        <dubbo:registry address="N/A" />
         
        <!-- 暴露服务协议配置 -->
        <dubbo:protocol name="dubbo" port="20813" />
        
        <!-- 暴露服务配置 -->
        <dubbo:service interface="com.alibaba.dubbo.config.spring.api.DemoService" 
        ref="demoService" />
         
        <bean id="demoService" 
        class="com.alibaba.dubbo.config.spring.impl.DemoServiceImpl" />
     
    </beans>

    spring加载xml或annotation,第一步需要将这些配置元数据载入spring容器中,首先确认下这些<dubbo:*>标签,对应的数据载体类。

    1. 认识标签对应的数据载体

    首先,找到dubbo-config\dubbo-config-spring\src\main\resources\META-INF\spring.handlers文件。找到负责具体解析dubbo标签的handler。

    http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler

    查看DubboNamespaceHandler 代码

    public class DubboNamespaceHandler extends NamespaceHandlerSupport {
    
       static {
          Version.checkDuplicate(DubboNamespaceHandler.class);
       }
    
       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("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
            registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
            registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
            registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
            registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
            registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
            registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
        }
    
    }

    不再进行分析具体代码了。这部分内容和spring的范畴。

    1.1对应表格

    标签
    数据配置类
    含义
    <dubbo:application name="demo-provider" />
    ApplicationConfig
    应用级别
    <dubbo:registry address="N/A" />
    RegistryConfig
    注册中心
    <dubbo:protocol name="dubbo" 
    port="20813" />
    ProtocolConfig协议
    <dubbo:service interface=".." 
    ref="demoService" />
    ServiceBean
    服务
    module
    ModuleConfig
    模块
    monitorMonitorConfig
    监控
    consumerConsumerConfig消费者
    provider
    ProviderConfig提供者
    reference
    ReferenceBean服务引用

    1.2 Config层次结构

    wKiom1hWaZjBJQW_AABLM5B6bOY383.png



    现在,应该很容易找出声明服务的配置入口是哪一个配置类:ServiceBean。其他的类,可以暂时靠边站。其他的配置信息(如ApplicationConfig,RegistryConfig..)主要涉及配置元数据,会决定dubbo运行时行为,但对梳理剖析DUBBO流程不太重要。

    2.认识ServiceBean

    ServiceBean是声明暴露Service的一个重要组件,需要重点关注。

    2.1结构树

    wKioL1hWbIzQUhrNAABPVdsPmdk818.png

    还是要感谢spring提供的优秀扩展特性,ServiceBean实现了很多spring的扩展接口。现在,把重点放在AbstractConfig继承树这个层次上。

    AbstractConfig提供基础支持方法,比如appendAttributes,check*系列方法等。

    AbstractMethodConfig,封装了一些方法级别的相关属性

    AbstractInterfaceConfig:封装了接口契约需要的属性

    AbstractServiceConfig:    服务相关属性(重在使用运维级别)

    ServiceConfig:主要包含一些运行时数据


    AbstractMethodConfig 属性片段

    public abstract class AbstractMethodConfig extends AbstractConfig {
    // 远程调用超时时间(毫秒)
    protected Integer             timeout;
    
    // 重试次数
    protected Integer             retries;
    
    // 最大并发调用
    protected Integer             actives;
    
    // 负载均衡
    protected String              loadbalance;
    
    // 是否异步
    protected Boolean             async;
    
    // 异步发送是否等待发送成功
    protected Boolean             sent;
    
    // 服务接口的失败mock实现类名
    protected String              mock;
    
    // 合并器
    protected String              merger;
    
    // 服务接口的失败mock实现类名
    protected String              cache;
    
    // 服务接口的失败mock实现类名
    protected String              validation;
    ..
    }

    AbstractInterfaceConfig.java属性片段

    public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
    
        private static final long      serialVersionUID = -1559314110797223229L;
    
        // 服务接口的本地实现类名
        protected String               local;
    
        // 服务接口的本地实现类名
        protected String               stub;
    
        // 服务监控
        protected MonitorConfig        monitor;
        
        // 代理类型
        protected String               proxy;
        
        // 集群方式
        protected String               cluster;
    
        // 过滤器
        protected String               filter;
        
        // 监听器
        protected String               listener;
    
        // 负责人
        protected String               owner;
    
        // 连接数限制,0表示共享连接,否则为该服务独享连接数
        protected Integer              connections;
        
        // 连接数限制
        protected String               layer;
        
        // 应用信息
        protected ApplicationConfig    application;
        
        // 模块信息
        protected ModuleConfig         module;
    
        // 注册中心
        protected List<RegistryConfig> registries;
        
        // callback实例个数限制
        private Integer                callbacks;
        
        // 连接事件
        protected String              onconnect;
        
        // 断开事件
        protected String              ondisconnect;
    
        // 服务暴露或引用的scope,如果为local,则表示只在当前JVM内查找.
       private String scope;
       ...
       }

    AbstractServiceConfig 属性片段

    public abstract class AbstractServiceConfig extends AbstractInterfaceConfig {
    
        private static final long      serialVersionUID = 1L;
    
        // 服务版本
        protected String               version;
    
        // 服务分组
        protected String               group;
    
        // 服务是否已经deprecated
        protected Boolean              deprecated;
    
        // 延迟暴露
        protected Integer              delay;
    
        // 是否暴露
        protected Boolean              export;
    
        // 权重
        protected Integer              weight;
    
        // 应用文档
        protected String               document;
    
        // 在注册中心上注册成动态的还是静态的服务
        protected Boolean              dynamic;
    
        // 是否使用令牌
        protected String               token;
    
        // 访问日志
        protected String               accesslog;
    
        // 允许执行请求数
        private Integer                executes;
    
        protected List<ProtocolConfig> protocols;
    
        // 是否注册
        private Boolean                register;
        ...
        }

    ServiceConfig.java属性片段

    public class ServiceConfig<T> extends AbstractServiceConfig {
    
        private static final long   serialVersionUID = 3033787999037024738L;
    
        private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
        
        private static final ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
    
        private static final Map<String, Integer> RANDOM_PORT_MAP = new HashMap<String, Integer>();
    
        // 接口类型
        private String              interfaceName;
    
        private Class<?>            interfaceClass;
    
        // 接口实现类引用
        private T                   ref;
    
        // 服务名称
        private String              path;
    
        // 方法配置
        private List<MethodConfig>  methods;
    
        private ProviderConfig provider;
    
        private final List<URL> urls = new ArrayList<URL>();
        
        private final List<Exporter<?>> exporters = new ArrayList<Exporter<?>>();
    
        private transient volatile boolean exported;
    
       private transient volatile boolean unexported;
        
        private transient volatile boolean generic;
        ...
        }

    注意ServiceConfig 有几个很服务声明有关的属性

        private final List<Exporter<?>> exporters = new ArrayList<Exporter<?>>();
    
        private transient volatile boolean exported;
    
        private transient volatile boolean unexported;

    这是剖析服务声明的入口。

关键字