程序员你是如何使用Nacos作为配置中心的?

假如你使用的是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=true
spring.cloud.nacos.config.refresh-enabled=true
spring.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.properties
spring.cloud.nacos.config.shared-configs[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.shared-configs[0].refresh=true
位置: 模块start下的src/main/resources/bootstrap.properties文件中
自描述的配置信息,即引入的共享配置文件列表有哪些,可以按照需要,配置各种中间件的配置信息;
| key | 说明 |
|---|---|
| data-id | _the data id of extended configuration 配置文件名称,带上后缀;翻译:扩展配置文件的数据id |
| group | _the 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:6379 | r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:6379 | 是 |
| 在服务独有app-file.properties配置中重写配置redis.config.servers=r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:637905 | r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:637905 | r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:637905 | 是 |
截图如下:



源码分析
掌握用法之后,深入分析源码,知其然而知其所以然;
starter调用封装
使用的starter封装;
版本: 2.2.1.RELEASE
启动的时候自动装配的配置如下:
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.alibaba.cloud.nacos.NacosConfigBootstrapConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.cloud.nacos.NacosConfigAutoConfiguration,\
com.alibaba.cloud.nacos.endpoint.NacosConfigEndpointAutoConfiguration
org.springframework.boot.diagnostics.FailureAnalyzer=\
com.alibaba.cloud.nacos.diagnostics.analyzer.NacosConnectionFailureAnalyzer
分解一下key,看一下用途:
| key | 说明 |
|---|---|
| org.springframework.cloud.bootstrap.BootstrapConfiguration | A 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
| 序号 | 说明 |
|---|---|
| 1 | NacosConfigProperties nacos配置 |
| 2 | NacosRefreshProperties 已经不建议被使用 |
| 3 | NacosRefreshHistory 刷新历史 |
| 4 | NacosConfigManager 配置 |
| 5 | NacosContextRefresher 注册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的客户端源码分析中可看到一些配置优先级的顺序。
原创不易,关注诚可贵,转发价更高!转载请注明出处,让我们互通有无,共同进步,欢迎沟通交流。
程序员你是如何使用Nacos作为配置中心的?的更多相关文章
- Nacos作为配置中心时,多个服务共用一个dataId的配置
写在前面 本文是对我之前一篇文章<Spring Cloud+nacos+Feign,实现注册中心及配置中心>的补充.此文章中简单写了如何将Nacos作为配置中心.在使用配置中心时,我们会遇 ...
- SpringBoot项目使用Nacos作为配置中心
前置条件:jdk.SpringBoot项目.Nacos.Linux服务器(可无) 具体版本:jdk11.SpringBoot 2.3.5.RELEASE.Nacos 2.0.3.Centos 6 目标 ...
- Nacos系列:基于Nacos的配置中心
前言 在看正文之前,我想请你回顾一下自己待过的公司都是怎么管理配置的,我想应该会有以下几种方式: 1.硬编码 没有什么配置不配置的,直接写在代码里面,比如使用常量类 优势:对开发友好,开发清楚地知道代 ...
- Nacos(四):SpringCloud项目中接入Nacos作为配置中心
前言 通过前两篇文章: Nacos(二):Nacos与OpenFeign的对接使用 Nacos(三):SpringCloud项目中接入Nacos作为注册中心 相信大家已经对Nacos作为注册中心的基本 ...
- java架构之路-(微服务专题)feign的基本使用和nacos的配置中心
上次回归: 上次我们说了ribbon的基本使用,包括里面的内部算法,算法的细粒度配置,还有我们自己如何实现我们自己的算法,主要还是一些基本使用的知识,还不会使用ribbon的小伙伴可以回去看一下上一篇 ...
- nacos作为配置中心动态刷新@RefreshScope添加后取值为null的一个问题
之前springboot项目常量类如下形式: @Component @RefreshScope//nacos配置中心时添加上 public class Constants { @Value(" ...
- 使用nacos作为配置中心统一管理配置
基础环境 引入所需依赖包 <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>s ...
- 程序员如何让自己 Be Cloud Native - 配置篇
前言 这是<程序员如何让自己 Be Cloud Native>系列文章的第二篇,从第一篇的反馈来看,有些同学反馈十二要素太形式主义,不建议盲目跟从.作者认为任何理论和技术都需要有自己的观点 ...
- Spring Cloud Alibaba基础教程:使用Nacos作为配置中心
通过本教程的前两篇: <Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现> <Spring Cloud Alibaba基础教程:支持的几种服务消费方 ...
随机推荐
- private protected internal public
//C#中的访问修饰符: //private,私有访问修饰符,被private访问修饰符修饰的成员只有在当前类的内部可以访问,其他地方一律不能访问[类中成员,如果不写访问修饰符则默认都是私有的] // ...
- 重要bug记录
导唱功能:需求点分析:本地已下载歌曲播放,判断是否有音频原唱伴奏版权,无版权按钮显示“导唱”,有版权显示“播原唱”.程序实现逻辑: 1.下载歌曲时调用一个歌曲信息接口,返回歌曲的一些属性信息,其中包括 ...
- github travis-ci持续部署hexo博客
引言 目前我的博客源码是在coding上的,因为有很方便的持续部署,但是coding目前还不提供push文件的开放API. 因为最近做了一个一键分发平台,将博客分发到简书.CSDN等等的平台,但是我的 ...
- asp.net中 使用Nginx 配置 IIS站点负载均衡
这是一偏初学者入门的内容,发现有问题的地方,欢迎留言,一起学习,一起进步 本文主要记录一下在Windows平台中,IIS站点如何使用Nginx 做一个简单的负载均衡 一. 准备工作: 官网下载安装包 ...
- 鼠标移到图片上图片放大【css3实例】
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 来讲讲你对ThreadLocal的理解
前言 面试的时候被问到ThreadLocal的相关知识,没有回答好(奶奶的,现在感觉问啥都能被问倒),所以我决定先解决这几次面试中都遇到的高频问题,把这几个硬骨头都能理解的透彻的说出来了,感觉最起码不 ...
- Codeforces Round #670 (Div. 2) 深夜掉分(A - C题补题)
1406A. Subset Mex https://codeforces.com/contest/1406/problem/A Example input 4 6 0 2 1 5 0 1 3 0 1 ...
- mac如何安装YaPi
首先介绍一下YaPi是干什么的. 帮助开发者轻松创建.发布.维护 API,YApi 还为用户提供了优秀的交互体验,开发人员只需利用平台提供的接口数据写入工具以及简单的点击操作就可以实现接口的管理.免费 ...
- 漏洞扫描工具acunetix12会遇到的问题
1.如果安装好之后,打开工具时显示无法访问,首先去看任务管理器当中,acunetix的服务是否启动了 2.如果忘记了账号密码,可以在安装目录下,双击ChangePassword.exe进行重置密码
- 第24课 - #pragma 使用分析
第24课 - #pragma 使用分析 1. #pragma简介 (1)#pragma 是一条预处理器指令 (2)#pragma 指令比较依赖于具体的编译器,在不同的编译器之间不具有可移植性,表现为两 ...