Dubbo3 源码解读-宋小生-9:Dubbo启动器DubboBootstrap添加应用程序的配置信息ApplicationConfig

简介: > Dubbo3 已经全面取代 HSF2 成为阿里的下一代服务框架,2022 双十一基于 Dubbo3 首次实现了关键业务不停推、不降级的全面用户体验提升,从技术上,大幅提高研发与运维效率的同时地址推送等关键资源利用率提升超 40%,基于三位一体的开源中间件体系打造了阿里在云上的单元化最佳实践和统一标准,同时将规模化实践经验与技术创新贡献开源社区,极大的推动了开源技术与标准的发展。> 本文是
Dubbo3 已经全面取代 HSF2 成为阿里的下一代服务框架,2022 双十一基于 Dubbo3 首次实现了关键业务不停推、不降级的全面用户体验提升,从技术上,大幅提高研发与运维效率的同时地址推送等关键资源利用率提升超 40%,基于三位一体的开源中间件体系打造了阿里在云上的单元化最佳实践和统一标准,同时将规模化实践经验与技术创新贡献开源社区,极大的推动了开源技术与标准的发展。

本文是 Dubbo 社区贡献者宋小生基于 Dubbo3 3.0.8 版本撰写的源码解析博客,在 Dubbo3 开源&内部技术栈统一的情况下,期望能对集团内的开发者了解 Dubbo3 背后的实现原理有所帮助。可点此查看 博客原文

本篇是宋小生系列 9/30 篇。同时,由 Dubbo3 团队领导的源码解读系列也正在进行中,感兴趣的同学可加入钉钉群了解详情: 28165003194

9.1 简介

先贴个代码用来参考:

 DubboBootstrap bootstrap = DubboBootstrap.getInstance();
 bootstrap.application(new ApplicationConfig("dubbo-demo-api-provider"))
            .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
            .protocol(new ProtocolConfig(CommonConstants.DUBBO, -1))
            .service(service)
            .start()
            .await();

上个博客我们说了启动器对象的创建,启动器对象在启动之前是要初始化一些配置信息的,这里我们来看这一行代码:

bootstrap.application(new ApplicationConfig("dubbo-demo-api-provider"))

9.2 应用程序ApplicationConfig的配置信息

ApplicationConfig的构造器比较简单就是为他的成员变量name赋值来标识这个应用程序的名字
下面我们直接参考下官网的配置表格:

属性 对应URL参数 类型 是否必填 缺省值 作用 描述 兼容性
name application string 必填 服务治理 当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样,此参数不是匹配条件,你当前项目叫什么名字就填什么,和提供者消费者角色无关,比如:kylin应用调用了morgan应用的服务,则kylin项目配成kylin,morgan项目配成morgan,可能kylin也提供其它服务给别人使用,但kylin项目永远配成kylin,这样注册中心将显示kylin依赖于morgan 1.0.16以上版本
version application.version string 可选 服务治理 当前应用的版本 2.2.0以上版本
owner owner string 可选 服务治理 应用负责人,用于服务治理,请填写负责人公司邮箱前缀 2.0.5以上版本
organization organization string 可选 服务治理 组织名称(BU或部门),用于注册中心区分服务来源,此配置项建议不要使用autoconfig,直接写死在配置中,比如china,intl,itu,crm,asc,dw,aliexpress等 2.0.0以上版本
architecture architecture string 可选 服务治理 用于服务分层对应的架构。如,intl、china。不同的架构使用不同的分层。 2.0.7以上版本
environment environment string 可选 服务治理 应用环境,如:develop/test/product,不同环境使用不同的缺省值,以及作为只用于开发测试功能的限制条件 2.0.0以上版本
compiler compiler string 可选 javassist 性能优化 Java字节码编译器,用于动态类的生成,可选:jdk或javassist 2.1.0以上版本
logger logger string 可选 slf4j 性能优化 日志输出方式,可选:slf4j,jcl,log4j,log4j2,jdk 2.2.0以上版本
metadata-type metadata-type String 可选 local 服务治理 metadata 传递方式,是以 Provider 视角而言的,Consumer 侧配置无效,可选值有: remote - Provider 把 metadata 放到远端注册中心,Consumer 从注册中心获取 local - Provider 把 metadata 放在本地,Consumer 从 Provider 处直接获取 2.7.6以上版本

官网的配置很详细了上面有一些属性是值得注意的比如这个name,compiler,logger,metadata-type 我们可能要多看下默认值是什么,方便我们在使用过程中遇到问题的排查

常用的属性参考官网的表格已经足够了,不过上面的属性不是列举了所有的属性,后续应该官方文档回更新:
我这里把缺失的一些属性列举出来:

变量 类型 说明
registries List 应用级注册中心列表
registryIds String 注册中心id列表
monitor MonitorConfig 应用级监控配置
dumpDirectory String 保存线程转储的目录
qosEnable Boolean 是否启用qos
qosHost String 要侦听的qos主机地址
qosPort Integer 要侦听的qos端口
qosAcceptForeignIp Boolean qos是否接收外部IP
parameters Map<String, String> 自定义参数
shutwait String 应用程序关闭时间 赋值属性的时候会想系统属性dubbo.service.shutdown.wait里面存一份
hostname String 主机名
registerConsumer Boolean 用于控制是否将实例注册到注册表。仅当实例是纯消费者时才设置为“false”。
repository String 没找到哪里用了
enableFileCache Boolean 是否开启本地文件缓存
protocol String 此应用程序的首选协议(名称)适用于难以确定哪个是首选协议的地方
metadataServiceProtocol String 用于点对点的元数据传输的协议
metadataServicePort Integer 元数据服务端口号,用于服务发现
livenessProbe String Liveness 存活探针 用于设置qos中探测器的扩展
readinessProbe String Readiness 就绪探针
startupProbe String Startup 启动探针
registerMode String 注册模式,实例级,接口集,所有
enableEmptyProtection Boolean 接收到的空url地址列表和空保护被禁用,将清除当前可用地址

这里我们先来简单了解下这个实体类型的基本配置,直接看配置可能不太好理解,后面我们讲到每个配置的时候可以回来参考一下

应用程序配置对象添加到启动器中的配置管理器中

了解了配置信息再回过头来看下这个配置信息如何存放到启动器里面的:

我们的Demo调用代码如下:

 DubboBootstrap bootstrap = DubboBootstrap.getInstance();
 bootstrap.application(new ApplicationConfig("dubbo-demo-api-provider"))

DubboBootstrap的application方法设置一个应用程序配置ApplicationConfig对象

 public DubboBootstrap application(ApplicationConfig applicationConfig) {
         //将启动器构造器中初始化的默认应用程序模型对象传递给配置对象
        applicationConfig.setScopeModel(applicationModel);
        //将配置信息添加到配置管理器中
        configManager.setApplication(applicationConfig);
        return this;
    }

ConfigManager配置管理器的setApplication方法

  @DisableInject
    public void setApplication(ApplicationConfig application) {
        addConfig(application);
    }

ConfigManager配置管理器的addConfig方法

public final <T extends AbstractConfig> T addConfig(AbstractConfig config) {
        
        if (config == null) {
            return null;
        }
        // ignore MethodConfig
        //检查当前配置管理器支持管理的配置对象
        //目前支持的配置有ApplicationConfig,MonitorConfig,MetricsConfig,SslConfig,
        //ProtocolConfig,RegistryConfig,ConfigCenterConfig,MetadataReportConfig
        if (!isSupportConfigType(config.getClass())) {
            throw new IllegalArgumentException("Unsupported config type: " + config);
        }
        
        if (config.getScopeModel() != scopeModel) {
            config.setScopeModel(scopeModel);
        }
        
        //缓存中是否存在
        Map<String, AbstractConfig> configsMap = configsCache.computeIfAbsent(getTagName(config.getClass()), type -> new ConcurrentHashMap<>());

        // fast check duplicated equivalent config before write lock
        //不是服务级配置则直接从缓存中读取到配置之后直接返回
        if (!(config instanceof ReferenceConfigBase || config instanceof ServiceConfigBase)) {
            for (AbstractConfig value : configsMap.values()) {
                if (value.equals(config)) {
                    return (T) value;
                }
            }
        }

        // lock by config type
        //添加配置
        synchronized (configsMap) {
            return (T) addIfAbsent(config, configsMap);
        }
    }

ConfigManager配置管理器的addIfAbsent方法:

private <C extends AbstractConfig> C addIfAbsent(C config, Map<String, C> configsMap)
        throws IllegalStateException {
        //配置信息为空直接返回
        if (config == null || configsMap == null) {
            return config;
        }

        // find by value
        //根据配置规则判断,配置存在则返回
        Optional<C> prevConfig = findDuplicatedConfig(configsMap, config);
        if (prevConfig.isPresent()) {
            return prevConfig.get();
        }
        
        //生成配置key
        String key = config.getId();
        if (key == null) {
            do {
                // generate key if id is not set
                key = generateConfigId(config);
            } while (configsMap.containsKey(key));
        }

        //不相同的配置key重复则抛出异常
        C existedConfig = configsMap.get(key);
        if (existedConfig != null && !isEquals(existedConfig, config)) {
            String type = config.getClass().getSimpleName();
            logger.warn(String.format("Duplicate %s found, there already has one default %s or more than two %ss have the same id, " +
                    "you can try to give each %s a different id, override previous config with later config. id: %s, prev: %s, later: %s",
                type, type, type, type, key, existedConfig, config));
        }

        // override existed config if any
        //将配置对象存入configsMap对象中,configsMap来源于configsCache
        configsMap.put(key, config);
        return config;
    }

原文: <<Dubbo启动器DubboBootstrap添加应用程序的配置信息ApplicationConfig>>

目录
相关文章
|
6月前
|
缓存 Dubbo Java
Dubbo 第三节_ Dubbo的可扩展机制SPI源码解析
Dubbo会对DubboProtocol对象进⾏依赖注⼊(也就是⾃动给属性赋值,属性的类型为⼀个接⼝,记为A接⼝),这个时候,对于Dubbo来说它并不知道该给这个属性赋什么值,换句话说,Dubbo并不知道在进⾏依赖注⼊时该找⼀个什么的的扩展点对象给这个属性,这时就会预先赋值⼀个A接⼝的⾃适应扩展点实例,也就是A接⼝的⼀个代理对象。在调⽤getExtension去获取⼀个扩展点实例后,会对实例进⾏缓存,下次再获取同样名字的扩展点实例时就会从缓存中拿了。Protocol是⼀个接。但是,不是只要在⽅法上加了。
|
27天前
|
Dubbo 应用服务中间件 Apache
Dubbo 应用切换 ZooKeeper 注册中心实例,流量无损迁移
如果 Dubbo 应用使用 ZooKeeper 作为注册中心,现在需要切换到新的 ZooKeeper 实例,如何做到流量无损?
18 4
|
2月前
|
缓存 负载均衡 Dubbo
Dubbo技术深度解析及其在Java中的实战应用
Dubbo是一款由阿里巴巴开源的高性能、轻量级的Java分布式服务框架,它致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
78 6
|
4月前
|
Kubernetes Dubbo Cloud Native
如何将Dubbo应用接入服务网格
介绍使用传统Dubbo微服务体系的客户要如何将自己的服务接入到服务网格这一新一代云原生基础设施。
|
5月前
|
XML 监控 Dubbo
Dubbo怎么配置监控中心
**摘要:** 本文介绍了如何配置Dubbo的简单监控中心。首先,通过添加`&lt;dubbo:monitor protocol=&quot;registry&quot; /&gt;`到配置文件启用监控。接着,修改`dubbo.properties`设置Zookeeper地址。启动监控中心,服务提供者和消费者需添加`monitorEnabled=&quot;true&quot;`以开启监控功能。配置完成后,监控中心的Web界面能展示服务状态和性能指标,助力开发者和运维人员实时监控服务健康。
|
6月前
|
Dubbo Cloud Native 应用服务中间件
【Dubbo3 终极特性】「云原生三中心架构」带你探索 Dubbo3 体系下的配置中心和元数据中心、注册中心的原理及开发实战(中)
【Dubbo3 终极特性】「云原生三中心架构」带你探索 Dubbo3 体系下的配置中心和元数据中心、注册中心的原理及开发实战(中)
193 1
|
6月前
|
Docker 容器
在docker中安装dubbo-admin,并且阿里云服务器配置
在docker中安装dubbo-admin,并且阿里云服务器配置
297 1
|
6月前
|
负载均衡 Dubbo Java
Dubbo 的心脏:理解和应用多种协议【十三】
Dubbo 的心脏:理解和应用多种协议【十三】
74 0
|
6月前
|
XML 负载均衡 Dubbo
了解Dubbo配置:优先级、重试和容错机制的秘密【五】
了解Dubbo配置:优先级、重试和容错机制的秘密【五】
336 0
|
6月前
|
Dubbo Java 应用服务中间件
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用