9-Dubbo启动器DubboBootstrap添加应用程序的配置信息ApplicationConfig

9.1 简介

先贴个代码用来参考:

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

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

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

9.2 应用程序ApplicationConfig的配置信息

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

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

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

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

变量类型说明
registriesList应用级注册中心列表
registryIdsString注册中心id列表
monitorMonitorConfig应用级监控配置
dumpDirectoryString保存线程转储的目录
qosEnableBoolean是否启用qos
qosHostString要侦听的qos主机地址
qosPortInteger要侦听的qos端口
qosAcceptForeignIpBooleanqos是否接收外部IP
parametersMap<String, String>自定义参数
shutwaitString应用程序关闭时间
hostnameString主机名
registerConsumerBoolean用于控制是否将实例注册到注册表。仅当实例是纯消费者时才设置为“false”。
repositoryString没找到哪里用了
enableFileCacheBoolean是否开启本地文件缓存
protocolString此应用程序的首选协议(名称)适用于难以确定哪个是首选协议的地方
metadataServiceProtocolString用于点对点的元数据传输的协议
metadataServicePortInteger元数据服务端口号,用于服务发现
livenessProbeStringLiveness 存活探针 用于设置qos中探测器的扩展
readinessProbeStringReadiness 就绪探针
startupProbeStringStartup 启动探针
registerModeString注册模式,实例级,接口集,所有
enableEmptyProtectionBoolean接收到的空url地址列表和空保护被禁用,将清除当前可用地址

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

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

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

我们的Demo调用代码如下:

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

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

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

ConfigManager配置管理器的setApplication方法

  1. @DisableInject
  2. public void setApplication(ApplicationConfig application) {
  3. addConfig(application);
  4. }

ConfigManager配置管理器的addConfig方法

  1. public final <T extends AbstractConfig> T addConfig(AbstractConfig config) {
  2. if (config == null) {
  3. return null;
  4. }
  5. // ignore MethodConfig
  6. //检查当前配置管理器支持管理的配置对象
  7. //目前支持的配置有ApplicationConfig,MonitorConfig,MetricsConfig,SslConfig,
  8. //ProtocolConfig,RegistryConfig,ConfigCenterConfig,MetadataReportConfig
  9. if (!isSupportConfigType(config.getClass())) {
  10. throw new IllegalArgumentException("Unsupported config type: " + config);
  11. }
  12. if (config.getScopeModel() != scopeModel) {
  13. config.setScopeModel(scopeModel);
  14. }
  15. //缓存中是否存在
  16. Map<String, AbstractConfig> configsMap = configsCache.computeIfAbsent(getTagName(config.getClass()), type -> new ConcurrentHashMap<>());
  17. // fast check duplicated equivalent config before write lock
  18. //不是服务级配置则直接从缓存中读取到配置之后直接返回
  19. if (!(config instanceof ReferenceConfigBase || config instanceof ServiceConfigBase)) {
  20. for (AbstractConfig value : configsMap.values()) {
  21. if (value.equals(config)) {
  22. return (T) value;
  23. }
  24. }
  25. }
  26. // lock by config type
  27. //添加配置
  28. synchronized (configsMap) {
  29. return (T) addIfAbsent(config, configsMap);
  30. }
  31. }

ConfigManager配置管理器的addIfAbsent方法:

  1. private <C extends AbstractConfig> C addIfAbsent(C config, Map<String, C> configsMap)
  2. throws IllegalStateException {
  3. //配置信息为空直接返回
  4. if (config == null || configsMap == null) {
  5. return config;
  6. }
  7. // find by value
  8. //根据配置规则判断,配置存在则返回
  9. Optional<C> prevConfig = findDuplicatedConfig(configsMap, config);
  10. if (prevConfig.isPresent()) {
  11. return prevConfig.get();
  12. }
  13. //生成配置key
  14. String key = config.getId();
  15. if (key == null) {
  16. do {
  17. // generate key if id is not set
  18. key = generateConfigId(config);
  19. } while (configsMap.containsKey(key));
  20. }
  21. //不相同的配置key重复则抛出异常
  22. C existedConfig = configsMap.get(key);
  23. if (existedConfig != null && !isEquals(existedConfig, config)) {
  24. String type = config.getClass().getSimpleName();
  25. logger.warn(String.format("Duplicate %s found, there already has one default %s or more than two %ss have the same id, " +
  26. "you can try to give each %s a different id, override previous config with later config. id: %s, prev: %s, later: %s",
  27. type, type, type, type, key, existedConfig, config));
  28. }
  29. // override existed config if any
  30. //将配置对象存入configsMap对象中,configsMap来源于configsCache
  31. configsMap.put(key, config);
  32. return config;
  33. }

技术咨询支持,可以扫描微信公众号进行回复咨询
在这里插入图片描述