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>>

目录
相关文章
|
XML Cloud Native Dubbo
【Dubbo3高级特性】「提升系统安全性」手把手教你如何通过令牌进行Dubbo3服务验证及服务鉴权控制实战指南(一)
【Dubbo3高级特性】「提升系统安全性」手把手教你如何通过令牌进行Dubbo3服务验证及服务鉴权控制实战指南
1092 1
|
Dubbo Cloud Native 应用服务中间件
【Dubbo3 终极特性】「云原生三中心架构」带你探索 Dubbo3 体系下的配置中心和元数据中心、注册中心的原理及开发实战(中)
【Dubbo3 终极特性】「云原生三中心架构」带你探索 Dubbo3 体系下的配置中心和元数据中心、注册中心的原理及开发实战(中)
905 1
|
XML 监控 Dubbo
Dubbo怎么配置监控中心
**摘要:** 本文介绍了如何配置Dubbo的简单监控中心。首先,通过添加`&lt;dubbo:monitor protocol=&quot;registry&quot; /&gt;`到配置文件启用监控。接着,修改`dubbo.properties`设置Zookeeper地址。启动监控中心,服务提供者和消费者需添加`monitorEnabled=&quot;true&quot;`以开启监控功能。配置完成后,监控中心的Web界面能展示服务状态和性能指标,助力开发者和运维人员实时监控服务健康。
443 0
|
XML Dubbo Java
【Dubbo3高级特性】「提升系统安全性」手把手教你如何通过令牌进行Dubbo3服务验证及服务鉴权控制实战指南(二)
【Dubbo3高级特性】「提升系统安全性」手把手教你如何通过令牌进行Dubbo3服务验证及服务鉴权控制实战指南
913 0
|
Kubernetes Dubbo 应用服务中间件
【Dubbo3终极特性】「流量治理体系」一文教你如何搭建Dubbo3的控制台服务Dubbo-Admin
【Dubbo3终极特性】「流量治理体系」一文教你如何搭建Dubbo3的控制台服务Dubbo-Admin
660 0
|
Dubbo Java 应用服务中间件
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
|
Dubbo Java 应用服务中间件
Spring Cloud Dubbo:微服务通信的高效解决方案
【10月更文挑战第15天】随着信息技术的发展,微服务架构成为企业应用开发的主流。Spring Cloud Dubbo结合了Dubbo的高性能RPC和Spring Cloud的生态系统,提供高效、稳定的微服务通信解决方案。它支持多种通信协议,具备服务注册与发现、负载均衡及容错机制,简化了服务调用的复杂性,使开发者能更专注于业务逻辑的实现。
411 2
|
Dubbo Java 应用服务中间件
💥Spring Cloud Dubbo火爆来袭!微服务通信的终极利器,你知道它有多强大吗?🔥
【8月更文挑战第29天】随着信息技术的发展,微服务架构成为企业应用开发的主流模式,而高效的微服务通信至关重要。Spring Cloud Dubbo通过整合Dubbo与Spring Cloud的优势,提供高性能RPC通信及丰富的生态支持,包括服务注册与发现、负载均衡和容错机制等,简化了服务调用管理并支持多种通信协议,提升了系统的可伸缩性和稳定性,成为微服务通信领域的优选方案。开发者仅需关注业务逻辑,而无需过多关心底层通信细节,使得Spring Cloud Dubbo在未来微服务开发中将更加受到青睐。
295 0
|
Dubbo 应用服务中间件 Apache
Star 4w+,Apache Dubbo 3.3 全新发布,Triple X 领衔,开启微服务通信新时代
在 Apache Dubbo 突破 4w Star 之际,Apache Dubbo 团队正式宣布,Dubbo 3.3 正式发布!作为全球领先的开源微服务框架,Dubbo 一直致力于为开发者提供高性能、可扩展且灵活的分布式服务解决方案。此次发布的 Dubbo 3.3,通过 Triple X 的全新升级,突破了以往局限,实现了对南北向与东西向流量的全面支持,并提升了对云原生架构的友好性。
520 109
|
负载均衡 Dubbo 应用服务中间件
框架巨擘:Dubbo如何一统异构微服务江湖,成为开发者的超级武器!
【8月更文挑战第8天】在软件开发中,微服务架构因灵活性和可扩展性备受欢迎。面对异构微服务的挑战,Apache Dubbo作为高性能Java RPC框架脱颖而出。它具备服务注册与发现、负载均衡及容错机制等核心特性,支持多种通信协议和序列化方式,能有效连接不同技术栈的微服务。Dubbo的插件化设计保证了面向未来的扩展性,使其成为构建稳定高效分布式系统的理想选择。
399 80