美文网首页
DubboBootstrap启动类

DubboBootstrap启动类

作者: 爱健身的兔子 | 来源:发表于2021-02-06 10:35 被阅读0次

    1 DubboBootstrap的作用

    DubboBootstrap类是Dubbo中非常重要的启动类,主要功能包括:

    1. 持有ConfigManagerEnvironment对象并且对其初始化,这两个对象都是与配置相关的;
    2. 更新配置中心配置对象ConfigCenterConfig的属性值;
    3. 加载元数据中心对象;
    4. 检查各个配置对象的属性值是否合法;
    5. 注册java的关闭钩子;
    6. 服务端服务的暴露。

    该对象在一个dubbo实例中只能有一个,通过静态方法getInstance获取。getInstance方法调用DubboBootstrap的无参构造方法,在无参构造方法中创建了ConfigManagerEnvironment对象,之后将DubboShutdownHook关闭钩子注册到java中。

    1.1 ConfigManager

    ConfigManager存储了所有dubbo的配置对象:

    • RegistryConfig

    • ConsumerConfig

    • ModuleConfig

    • ProtocolConfig

    • ProviderConfig

    • ApplicationConfig

    • MonitorConfig

    类似于一个本地的配置中心,如果要查询配置信息,访问ConfigManager获取对应的配置对象即可,任何配置对象修改了,都要刷新ConfigManager,比如ApplicationConfig修改了属性值,便会调用refreshAll方法修改ConfigManager。 这些配置对象都存储在该对象的属性configsCache中,该属性是一个HashMap对象,因为HashMap不是线程安全的,所以提供了属性lock(ReadWriteLock对象)对访问属性configsCache的操作加锁。 ConfigManager提供了大量的setXXXaddXXX方法,这些方法最终都是调用addConfig方法,addConfig方法将配置对象添加到属性configsCache中。 属性configsCache的类型是Map<String, Map<String, AbstractConfig>>,是一个两层Map结构,第一层的key是配置类名字的变体,比如调用addMetadataReports增加MetadataReportConfig对象,那么第一层的key是metadata-report,也就是将类名字的Config去掉,然后在类名字中大写字母前加“-”,最后将所有的大写字母变为小写字母。第二层的key是配置对象中的id属性的值,如果没有设置id值,默认使用类名字+“#default”作为key。 在dubbo中,一般访问ConfigManager,是使用ApplicationModel.getConfigManager()通过SPI获取对象的。 因为AbstractConfigaddIntoConfigManager方法有注解@PostConstruct,因此在AbstractConfig对象创建完毕后,spring会自动调用addIntoConfigManager方法,在该方法中将配置对象添加到ConfigManager中。通过addIntoConfigManager方法保证了所有的配置对象都会存储到ConfigManager中。 DubboBootstrap也提供了大量的方法用于向ConfigManager中添加配置对象以及从ConfigManager中获取配置对象。

    1.2 Environment

    Environment也是存储配置信息,与ConfigManager不同的是,Environment主要处理的与系统配置相关,比如Java系统配置,以及配置中心的配置。 获取Environment对象,是通过ApplicationModel.getEnvironment()得到。

    Environment包含了如下几个配置对象:

    • PropertiesConfiguration装载"dubbo.properties"文件的配置信息;

    • SystemConfiguration装载System的properties配置系信息;

    • EnvironmentConfiguration装载JVM环境变量的配置信息;

    • InmemoryConfiguration装载内部的配置信息,分为全局配置和应用级配置;

    • DynamicConfiguration装载配置中心的配置信息;

    2 DubboBootstrap的启动

    DubboBootstrap的启动流程如下:

    public DubboBootstrap start() {
            //只能初始化一次
            if (started.compareAndSet(false, true)) {
                initialize();//调用初始化方法
                // 暴露服务
                exportServices();
                // Not only provider register
                if (!isOnlyRegisterProvider() || hasExportedServices()) {
                    // 暴露MetadataService
                    exportMetadataService();
                    // 注册服务实例
                    registerServiceInstance();
                }
                //引用
                referServices();
            }
            return this;
    }
    

    流程说明

    1. initialize,初始化系统;

    2. exportServices,暴露服务;

    3. isOnlyRegisterProviderhasExportedServices,判断是否需要暴露metadataService

    4. exportMetadataService,暴露MetadataService

    5. registerServiceInstance,将dubbo实例注册到专用于服务发现的注册中心;

    6. referServices,设置ReferenceConfigbootstrap属性;

    3 DubboBootstrap的初始化

    DubboBoostrap通过initialize方法实现初始化,主要包括初始化配置和环境,初始化元数据服务和监听器。

    private void initialize() {
        if (!initialized.compareAndSet(false, true)) {
            return;//initialize方法只能初始化一次
        }
        ApplicationModel.iniFrameworkExts();//初始化FrameworkExt实现类,这里会调用Environment的initialize方法
        startConfigCenter();//启动配置中心
        useRegistryAsConfigCenterIfNecessary();//用注册中心作为配置中心
        startMetadataReport();//启动MetadataReport
        loadRemoteConfigs();//加载远程配置
        checkGlobalConfigs();//检查全局配置
        initMetadataService();//初始化MetadataService
        initMetadataServiceExporter();//初始化MetadataServiceExporter
        initEventListener();//初始化事件监听器
    
    }
    
    3.1 ApplicationModel.iniFrameworkExts

    初始化FrameworkExt实现类,包括:

    • ConfigManager

    • Environment

    • ServiceRepository

    只有Environmentinitialize方法才有实现,Environment首先从ConfigManager获取默认的配置中心对象ConfigCenterConfig,如果存在ConfigCenterConfig对象,那么将ConfigCenterConfigexternalConfigurationappExternalConfiguration两个属性值设置到Environment的名字一致的两个属性上。

    3.2 startConfigCenter

    该方法从ConfigManager中获得的所有的ConfigCenterConfig对象。然后访问配置中心的配置,将这些配置保存到Environment对象,最后使用这些配置更新ApplicationConfigMonitorConfigModuleConfig等对象的属性。 配置中心可以有多个,在获取配置的时候,顺次访问每个配置中心,配置保存到本地时后访问的配置中心配置会覆盖之前的配置数据。

    3.3 useRegistryAsConfigCenterIfNecessary

    如果在方法startConfigCenter中,从ConfigManager里面没有找到ConfigCenterConfig对象,那么在本方法里面,会判断注册中心配置对象RegistryConfiguseAsConfigCenter值:

    1. 如果useAsConfigCenter=null或者true,那么就将注册中心作为配置中心,接下来创建对象ConfigCenterConfig,并将RegistryConfig中的地址、协议、用户名等信息设置到ConfigCenterConfig中,然后将ConfigCenterConfig对象添加到ConfigManager,最后再执行一次startConfigCenter

    2. 对于其他的useAsConfigCenter值,dubbo跳过该注册中心RegistryConfig

    useAsConfigCenter默认为null。dubbo可以配置多个注册中心和配置中心。

    3.4 startMetadataReport

    该方法主要是创建对象MetadataReport,建立与元数据中心的连接。 MetadataReportConfig是元数据中心,用于存储dubbo的元数据配置信息, ApplicationConfigmetadataType字段用于指定元数据中心的类型,有两个值:

    • remote

    • local

    该方法首先检查metadataType,如果类型是remote,那么必须配置MetadataReportConfig 。然后该方法使用SPI加载MetadataReportFactory对象,之后通过MetadataReportFactory对象创建MetadataReport对象,MetadataReport对象在构造方法中建立与元数据中心的连接。dubbo使用MetadataReport访问元数据中心。 元数据中心可以配置多个,但是只会使用其中一个。

    3.5 loadRemoteConfigs

    创建RegistryConfigProtocolConfig对象,并设置其属性。 该方法首先从Environment对象的appExternalConfigurationMapexternalConfigurationMap字段中获取所有的ProtocolConfigRegistryConfigid值,根据id值创建对应的RegistryConfigProtocolConfig对象。之后使用Environment对象设置RegistryConfigProtocolConfig对象的各个属性。以RegistryConfig的创建为例,代码如下:

        private void loadRemoteConfigs() {
            // registry ids to registry configs
            List<RegistryConfig> tmpRegistries = new ArrayList<>();
            Set<String> registryIds = configManager.getRegistryIds();
            registryIds.forEach(id -> {
                if (tmpRegistries.stream().noneMatch(reg -> reg.getId().equals(id))) {
                    tmpRegistries.add(configManager.getRegistry(id).orElseGet(() -> {
                        RegistryConfig registryConfig = new RegistryConfig();
                        registryConfig.setId(id);
                        registryConfig.refresh();
                        return registryConfig;
                    }));
                }
            });
    
            configManager.addRegistries(tmpRegistries);
    
            // protocol ids to protocol configs
            List<ProtocolConfig> tmpProtocols = new ArrayList<>();
            Set<String> protocolIds = configManager.getProtocolIds();
            protocolIds.forEach(id -> {
                if (tmpProtocols.stream().noneMatch(prot -> prot.getId().equals(id))) {
                    tmpProtocols.add(configManager.getProtocol(id).orElseGet(() -> {
                        ProtocolConfig protocolConfig = new ProtocolConfig();
                        protocolConfig.setId(id);
                        protocolConfig.refresh();
                        return protocolConfig;
                    }));
                }
            });
    
            configManager.addProtocols(tmpProtocols);
        }
    
    3.6 checkGlobalConfigs

    检查各个配置对象的各个属性设置的值是否合法,检查内容包括是否有非法字符,长度是否超长。 检查的对象包括:

    • ApplicationConfig

    • ConfigCenterConfig

    • MetadataReportConfig

    • MonitorConfig

    • MetricsConfig

    • ModuleConfig

    • SslConfig

    3.7 initMetadataService

    通过SPI加载WritableMetadataService实现类,实现类的名字是由ApplicationConfig类的metadataType字段指定的。

    WritableMetadataService包含两个实现类:

    • InMemoryWritableMetadataService

    • RemoteWritableMetadataService

    3.8 initMetadataServiceExporter

    initMetadataServiceExporter创建ConfigurableMetadataServiceExporter对象,将initMetadataService方法加载的WritableMetadataService对象作为其属性。ConfigurableMetadataServiceExporter的作用是将WritableMetadataService对象以dubbo服务的形式对外提供服务,这样客户端便可以使用dubbo协议访问MetadataService接口里面的方法。 initMetadataServiceExporter仅仅是创建ConfigurableMetadataServiceExporter对象,对外发布服务是在DubboBootstrapstart方法里面完成的。

    3.9 initEventListener

    本方法是将DubboBootstrap对象注册为监听器。 dubbo有自己实现的事件发布机制,其接口是EventDispatcher,默认实现是DirectEventDispatcherDubboBootstrap监听所有dubbo的org.apache.dubbo.event.Event事件。

    https://blog.csdn.net/weixin_38308374/article/details/105957522

    相关文章

      网友评论

          本文标题:DubboBootstrap启动类

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