Nacos既提供注册中心,也提供配置中心。下面分别以两个例子来说明配置中心的使用。
目录
案例一:配置中心使用
人工在Nacos配置内容
客户端使用
案例二:配置拆分与复用
背景
配置拆分复用说明
对pom.xml增加依赖
删除application.properties,增加bootstrap.properties
启动
调用验证
附1:Nacos config客户端临时暂存目录
附2:Nacos config隔离层次概念
附3:显示写入Nacos config配置中心及监听代码示例
Data ID: firstapp-dev.properties
Group : DEFAULT_GROUP
配置格式: Properties
配置内容: weather=sun
temperature=20.55
其中Data ID的命令规则为:应用名-环境profile名.文件后缀
新建一个project或者module。 在生成的默认pom.xml增加nacos-config和bootstrap依赖。如下
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.7.10
com.example
firstapp
0.0.1-SNAPSHOT
firstapp
firstapp
1.8
${java.version}
${java.version}
3.1.6
2021.0.4.0
UTF-8
org.springframework.boot
spring-boot-starter
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
${springcloudalibaba.version}
com.alibaba.nacos
nacos-client
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
${springcloudalibaba.version}
com.alibaba.nacos
nacos-client
com.alibaba.nacos
nacos-client
2.1.1
org.springframework.cloud
spring-cloud-starter-bootstrap
${springcloud.version}
org.springframework.boot
spring-boot-maven-plugin
创建bootstrap.properties文件(与application.properties文件同目录存放),bootstrap.properties加载顺序先于application.properties 。
bootstrap.properties文件内容如下:
spring.application.name=firstapp
#Data ID的前缀(如果不指定,则默认取 ${spring.appliction.name})
spring.cloud.nacos.config.prefix=firstapp
#指定为开发环境
spring.profiles.active=dev
#Nacos配置中心服务端的地址和端口(形式ip:port,ip:port,...) 前个地址不可用时,才会自动重连下一个地址
spring.cloud.nacos.config.server-addr=39.100.80.168:8848
#命名空间(由于Nacos自身Bug:若这里显示指定为public会导致高频刷,不显示指定或者指定其他命名空间均正常。 Bug链接 https://github.com/alibaba/nacos/issues/3460)
#spring.cloud.nacos.config.namespace=public
#配置组(如果不指定,则默认为DEFAULT_GROUP)
spring.cloud.nacos.config.group=DEFAULT_GROUP
#指定文件后缀(如果不指定,则默认为properties)
spring.cloud.nacos.config.file-extension=properties
对SpringBoot启动类中,增加获取配置项并输出的代码。
@SpringBootApplication
public class FirstappApplication {
public static void main(String[] args) throws InterruptedException {
ConfigurableApplicationContext applicationContext = SpringApplication.run(FirstappApplication.class, args);
while (true) {
String weather = applicationContext.getEnvironment().getProperty("weather");
String temperature = applicationContext.getEnvironment().getProperty("temperature");
System.err.println("weather:" + weather + "; temperature: " + temperature);
TimeUnit.SECONDS.sleep(3);
}
}
}
启动运行后,可以看到SpringBoot程序获得了Nacos配置中心的值。
同时,如果在Nacos控制台界面中人工调整配置项的值,SpringBoot会立即自动取得最新值。因为Nacos客户端带自动刷新功能。
可以通过配置
spring.cloud.nacos.config.refresh.enabled=false
来关闭自动刷新
本案例在前一个案例(https://blog.csdn.net/zyplanke/article/details/120849248)基础上进行注册中心修改。
在nacos中配置如下三个Data ID:
在Nacos中人工定义如上三个Data ID,内容分别如下:
commonshare.properties:
paymentService.properties:
orderService.properties:
------ 前面省略 ------
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
${springcloudalibaba.version}
com.alibaba.nacos
nacos-client
org.springframework.cloud
spring-cloud-starter-bootstrap
${springcloud.version}
------ 后面省略 ------
分别将payment、order服务下的application.properties文件中内容清空或直接删除该文件。
在payment服务下新增bootstrap.properties文件,改为从配置中心获取应用程序的配置,bootstrap.properties内容如下:
spring.application.name=payment
#Nacos配置中心服务端的地址和端口(形式ip:port,ip:port,...) 。注:nacos-client1.x会按顺序选其中地址进行连接(前个连接失败则自动选后一个)。nacos-client2.x会随机选其中地址进行连接(若连接失败则自动另选)
spring.cloud.nacos.config.server-addr=39.100.80.168:8848
#Data ID的前缀(如果不指定,则默认取 ${spring.appliction.name})
spring.cloud.nacos.config.prefix=paymentService
spring.cloud.nacos.config.group=DEFAULT_GROUP
#指定文件后缀(如果不指定,则默认为properties)
spring.cloud.nacos.config.file-extension=properties
#通用共享配置的信息
spring.cloud.nacos.config.shared-configs[0].data-id=commonshare.properties
spring.cloud.nacos.config.shared-configs[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.shared-configs[0].refresh=true
在order服务下新增bootstrap.properties文件,内容如下:
spring.application.name=order
#Nacos配置中心服务端的地址和端口(形式ip:port,ip:port,...) 。注:nacos-client1.x会按顺序选其中地址进行连接(前个连接失败则自动选后一个)。nacos-client2.x会随机选其中地址进行连接(若连接失败则自动另选)
spring.cloud.nacos.config.server-addr=39.100.80.168:8848
#Data ID的前缀(如果不指定,则默认取 ${spring.appliction.name})
spring.cloud.nacos.config.prefix=orderService
spring.cloud.nacos.config.group=DEFAULT_GROUP
#指定文件后缀(如果不指定,则默认为properties)
spring.cloud.nacos.config.file-extension=properties
#通用共享配置的信息
spring.cloud.nacos.config.shared-configs[0].data-id=commonshare.properties
spring.cloud.nacos.config.shared-configs[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.shared-configs[0].refresh=true
重新repackage模块payment、order,然后分别启动payment、order服务。
可以看到payment服务启动端口为9999(从nacos配置中心获得的端口配置);
可以看到order服务启动端口为4444(从nacos配置中心获得的端口配置)
curl http://localhost:4444/consumer/66
调用Order服务成功,返回信息符合预期。
注意1:注册中心和配置中心的Group两者是不同的,各自管各自。
注意2:以上层的设置,对于同一服务实例可以在Nacos注册中心、配置中心分别配置不同group。既同一个服务在向Nacos向Nacos获取配置时申明的group=A,而向Nacos注册服务时申明的group=B,这是允许的。
更多的关于springcloud中nacos config配置项可参加nacos官网:
Nacos config · alibaba/spring-cloud-alibaba Wiki · GitHub
在Java代码中显示的将配置内容写入发布至配置中心
a、 不使用Springboot Bean方式,通过以下方式直接访问Nacos服务端,向服务端写配置,或者读取配置:
ConfigService configService = NacosFactory.createConfigService(ServerAddrList);
configService.publishConfig("test.properties", "GJS_GROUP" , "aaa.bbb=111\nccc.ddd=222\nxxx=333");
configService.getConfig(String dataId, String group, long timeoutMs);
configService.shutDown();
b、 若在Springboot Bean中,通过自动注入获得configService对象:
@Autowired
NacosConfigManager nacosConfigManager;
...... 省略 ......
ConfigService configService = nacosConfigManager.getConfigService();
...... 然后使用该对象操作(省略)......
在Java代码增加对Nacos配置中心的配置项监听
向Nacos配置中心注册监听器,当Nacos配置中心的配置内容变化时,通过此监听器自动获取最新内容,并更新并保存本类变量中:
/**
* 向Nacos配置中心注册监听器
* 当Nacos配置中心的配置内容变化时,通过此监听器自动获取最新内容,并更新并保存本类变量中
*
*/
@Component
@Slf4j
public class NacosConfigListener {
public static Map exchCodeServiceNameMap = new HashMap<>(2000);
@Autowired
private void addNacosConfigListener(NacosConfigManager nacosConfigManager) {
ConfigService configService = nacosConfigManager.getConfigService();
try {
configService.addListener(Global.NacosConfigDataID_ExchCode_ServiceName_Map, Global.NacosConfigGroup_ExchCode_ServiceName_Map,
new PropertiesListener() {
@Override
public void innerReceive(Properties properties) {
properties.forEach((key, value) -> exchCodeServiceNameMap.put( (String) key, (String)value));
log.info("感知到Nacos配置中心dataID=[{}],group=[{}]发生变化,已将最新配置内容更新至本地对象", Global.NacosConfigDataID_ExchCode_ServiceName_Map,Global.NacosConfigGroup_ExchCode_ServiceName_Map );
}
});
log.info("作向Nacos配置中心注册器(监听配置变化)完成");
} catch (NacosException e) {
log.error("监听Nacos配置中心遇到异常", e);
}
}
}