如果你应用的是spring-cloud-alibaba微服务技术栈

单个服务独有配置文件

即去除应用程序的状态,配置对立内部化治理,不便进行程度的伸缩。

集成步骤:

如果我有一个利用app-design;

1,引入依赖:

<dependency>     <groupId>com.alibaba.cloud</groupId>     <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>     <version>2.2.1.RELEASE</version> </dependency>

2, 配置文件;

spring.cloud.nacos.config.enabled=truespring.cloud.nacos.config.refresh-enabled=truespring.cloud.nacos.config.server-addr=${spring.cloud.nacos.discovery.server-addr}spring.cloud.nacos.config.namespace=${spring.cloud.nacos.discovery.namespace}

阐明如下:

属性阐明
spring.cloud.nacos.config.server-addr=${spring.cloud.nacos.discovery.server-addr}nacos配置核心地址
spring.cloud.nacos.config.namespace=${spring.cloud.nacos.discovery.namespace}nacos的命名空间,这里跟服务发现的配置统一;

3,应用配置的形式,同本地配置文件一样。

@Value @PropertyConfiguration 这些注解都是反对的;

4,确认形式,比方把之前的application.properties的配置放到了配置核心;

本地启动的时候,读取到了8081端口和数据库连接池的配置;

配置核心的连贯原理,前面独自整理出来,知其然并知其所以然。

服务之间共享配置文件

场景:多个后端微服务,在同一个集群中共用中间件的配置信息。

比方 缓存redis, 音讯队列kafka, 文件服务器, 邮件服务器;

那么对应的配置文件没有必要在所有的后端微服务中独自存在,这些配置文件应该放在公共配置文件中,然而也能够被具体的后端微服务本人的独有配置文件笼罩,应用本人的公有配置;

可联合下图了解:

问题答复
where are we?现状中间件配置扩散在很多服务中,配置繁琐,不不便对立治理
where are we go?目标同一个集群的中间件只保护一份,各服务共享,也可依照须要笼罩共享的配置;
how can we go there?实现门路基于nacos已有性能实现

上面是理论的coding过程和测试用例;

服务app-file;

在服务对应的nacos的namespace中

1 引入共享配置

#共享中间件的配置spring.cloud.nacos.config.shared-configs[0].data-id=mid.propertiesspring.cloud.nacos.config.shared-configs[0].group=DEFAULT_GROUPspring.cloud.nacos.config.shared-configs[0].refresh=true

地位: 模块start下的src/main/resources/bootstrap.properties文件中

自描述的配置信息,即引入的共享配置文件列表有哪些,能够依照须要,配置各种中间件的配置信息;

key阐明
data-id_the data id of extended configuration 配置文件名称,带上后缀;翻译:扩大配置文件的数据id
groupthe group of extended configuration, the default value is DEFAULT_GROUP 集群名称, 从名字来看,反对多集群的配置文件 翻译:扩大配置文件的集群,默认值是 _DEFAULT_GROUP
refresh_whether to support dynamic refresh, the default does not support 是否刷新 翻译:是否反对动静刷新,默认不反对

花括号[0] ,外面的0是序号,如果有多个,依照数字自增程序进行配置;

2 在nacos中新增配置文件

依据理论场景在nacos的test命名空间中新增配置文件mid.properties

3 获取配置用例测试

测试接口代码:

 @ApiOperation("测试获取公共配置文件")    @GetMapping("/config/test")    public Response config(){        String redisConfigServers = environment.getProperty("redis.config.servers","null");        return SingleResponse.of(redisConfigServers);    }

测试用例:

场景冀望后果理论后果是否合乎预期
获取共享配置文件中的配置r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:6379r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:6379
在服务独有app-file.properties配置中重写配置redis.config.servers=r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:637905r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:637905r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:637905

截图如下:

源码剖析

把握用法之后,深入分析源码,知其然而知其所以然;

starter调用封装

应用的starter封装;

https://github.com/alibaba/spring-cloud-alibaba/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config

版本: 2.2.1.RELEASE

启动的时候主动拆卸的配置如下:

org.springframework.cloud.bootstrap.BootstrapConfiguration=\com.alibaba.cloud.nacos.NacosConfigBootstrapConfigurationorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.alibaba.cloud.nacos.NacosConfigAutoConfiguration,\com.alibaba.cloud.nacos.endpoint.NacosConfigEndpointAutoConfigurationorg.springframework.boot.diagnostics.FailureAnalyzer=\com.alibaba.cloud.nacos.diagnostics.analyzer.NacosConnectionFailureAnalyzer

合成一下key,看一下用处:

key阐明
org.springframework.cloud.bootstrap.BootstrapConfigurationA marker interface used as a key in META-INF/spring.factories. Entries in* the factories file are used to create the bootstrap application context.

翻译:一个标记注解用来作为key 放在META-INF/spring.factories文件中,文件中的条目用来创立启动利用的上下文;

起源:spring-cloud-context-version.jar

value:

com.alibaba.cloud.nacos.NacosConfigBootstrapConfiguration |
| org.springframework.boot.autoconfigure.EnableAutoConfiguration | 正文太长了,不放这里.放到附录中。

起源:spring-boot-autoconfigure-version.jar

com.alibaba.cloud.nacos.NacosConfigAutoConfiguration,\

com.alibaba.cloud.nacos.endpoint.NacosConfigEndpointAutoConfiguration |
| org.springframework.boot.diagnostics.FailureAnalyzer | A {@code FailureAnalyzer} is used to analyze a failure and provide diagnostic* information that can be displayed to the user.

_

翻译: FailureAnalyzer用来剖析谬误并提供诊断信息展现给到用户

起源: spring-boot-version.jar

com.alibaba.cloud.nacos.diagnostics.analyzer.NacosConnectionFailureAnalyzer |

而后看看都主动拆卸了什么?以及主动拆卸的过程。

springboot的形式调用;

1 NacosConfigBootstrapConfiguration

源码:

package com.alibaba.cloud.nacos;import com.alibaba.cloud.nacos.client.NacosPropertySourceLocator;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * @author xiaojing */@Configuration(proxyBeanMethods = false)@ConditionalOnProperty(name = "spring.cloud.nacos.config.enabled", matchIfMissing = true)public class NacosConfigBootstrapConfiguration {    @Bean    @ConditionalOnMissingBean    public NacosConfigProperties nacosConfigProperties() {        return new NacosConfigProperties();    }    @Bean    @ConditionalOnMissingBean    public NacosConfigManager nacosConfigManager(            NacosConfigProperties nacosConfigProperties) {        return new NacosConfigManager(nacosConfigProperties);    }    @Bean    public NacosPropertySourceLocator nacosPropertySourceLocator(            NacosConfigManager nacosConfigManager) {        return new NacosPropertySourceLocator(nacosConfigManager);    }}

主动拆卸流程:

配置文件组装源码:

@Override    public PropertySource<?> locate(Environment env) {        nacosConfigProperties.setEnvironment(env);        ConfigService configService = nacosConfigManager.getConfigService();        if (null == configService) {            log.warn("no instance of config service found, can't load config from nacos");            return null;        }        long timeout = nacosConfigProperties.getTimeout();        nacosPropertySourceBuilder = new NacosPropertySourceBuilder(configService,                timeout);        String name = nacosConfigProperties.getName();        String dataIdPrefix = nacosConfigProperties.getPrefix();        if (StringUtils.isEmpty(dataIdPrefix)) {            dataIdPrefix = name;        }        if (StringUtils.isEmpty(dataIdPrefix)) {            dataIdPrefix = env.getProperty("spring.application.name");        }        CompositePropertySource composite = new CompositePropertySource(                NACOS_PROPERTY_SOURCE_NAME);        loadSharedConfiguration(composite);        loadExtConfiguration(composite);        loadApplicationConfiguration(composite, dataIdPrefix, nacosConfigProperties, env);        return composite;    }

加载利用配置文件的程序源码:

private void loadApplicationConfiguration(            CompositePropertySource compositePropertySource, String dataIdPrefix,            NacosConfigProperties properties, Environment environment) {        String fileExtension = properties.getFileExtension();        String nacosGroup = properties.getGroup();        // load directly once by default        loadNacosDataIfPresent(compositePropertySource, dataIdPrefix, nacosGroup,                fileExtension, true);        // load with suffix, which have a higher priority than the default        loadNacosDataIfPresent(compositePropertySource,                dataIdPrefix + DOT + fileExtension, nacosGroup, fileExtension, true);        // Loaded with profile, which have a higher priority than the suffix        for (String profile : environment.getActiveProfiles()) {            String dataId = dataIdPrefix + SEP1 + profile + DOT + fileExtension;            loadNacosDataIfPresent(compositePropertySource, dataId, nacosGroup,                    fileExtension, true);        }    }

程序如下:

序号阐明
1加载dataIdPrefix对应的配置文件
2加载dataIdPrefix.fileExtension对应的配置文件
3加载 dataIdPrefix-activeProfiles.fileExtension对应的配置文件

2.1 NacosConfigAutoConfiguration

序号阐明
1NacosConfigProperties  nacos配置
2NacosRefreshProperties  曾经不倡议被应用
3NacosRefreshHistory  刷新历史
4NacosConfigManager 配置
5NacosContextRefresher 注册nacos的监听器到利用

2.2 NacosConfigEndpointAutoConfiguration

NacosConfigEndpoint

本地配置同步逻辑

    @ReadOperation    public Map<String, Object> invoke() {        Map<String, Object> result = new HashMap<>(16);        result.put("NacosConfigProperties", properties);        List<NacosPropertySource> all = NacosPropertySourceRepository.getAll();        List<Map<String, Object>> sources = new ArrayList<>();        for (NacosPropertySource ps : all) {            Map<String, Object> source = new HashMap<>(16);            source.put("dataId", ps.getDataId());            source.put("lastSynced", dateFormat.get().format(ps.getTimestamp()));            sources.add(source);        }        result.put("Sources", sources);        result.put("RefreshHistory", refreshHistory.getRecords());        return result;    }

NacosConfigHealthIndicator

健康检查 UP,DOWN,UNKNOWN ;

3 NacosConnectionFailureAnalyzer

连贯不上nacos服务端抛出异样

@Override    protected FailureAnalysis analyze(Throwable rootFailure,            NacosConnectionFailureException cause) {        return new FailureAnalysis(                "Application failed to connect to Nacos server: \""                        + cause.getServerAddr() + "\"",                "Please check your Nacos server config", cause);    }

小结:服务通过集成该starter,通过http申请从nacos的服务端拉取配置数据,并做了 配置刷新历史,注册监听器到spring容器中, 本地缓存,和错误报告;

服务端封装

源码地位:https://github.com/alibaba/nacos/tree/develop/config

利用启动读取配置文件整体调用链:待后续实现;

小结

如果读完本篇文章你只能记住一句话:nacos作为配置核心可为独自的服务提供内部化配置文件,也反对多利用共享配置文件。
从nacos的客户端源码剖析中可看到一些配置优先级的程序。
原创不易,关注诚可贵,转发价更高!转载请注明出处,让咱们互通有无,共同进步,欢送沟通交流。