美文网首页Java高开发Java 杂谈Java
Dubbo点滴之服务配置ServiceConfig

Dubbo点滴之服务配置ServiceConfig

作者: java高并发 | 来源:发表于2019-05-13 18:02 被阅读6次

    接触过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对应表格

    image.png

    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;
    

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

    在此我向大家推荐一个Java群 :219571750 里面会分享一些资深架构师录制的视频录像:(有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构、面试资料)等这些成为架构师必备的知识体系 进群马上免费领取,目前受益良多!

    c7e216aff31d4751bafba4a4ed9420e8.jpg

    相关文章

      网友评论

        本文标题:Dubbo点滴之服务配置ServiceConfig

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