本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、安装nacos
- 下载nacos 官网:github.com/alibaba/nac…
我是安装到linux,则下载****.tar.gz
- 解压 下载完成的nacos-server-1.2.1.tar.gz进行解压
解压命令: tar zxvf nacos-server-1.2.1.tar.gz
- 启动nacos 解压后进入到bin目录,然后执行命令:
sh startup.sh -m standalone 该方式启动,是单机模式启动。
- 报错 若发现启动完成报错:java.io.FileNotFoundException: /data/nacos/conf/cluster.conf (No such file or directory)
简单粗暴的解决方式:
- vim startup.sh
- 将脚本中的 if [ "{MODE}" = "standalone" ]; 即可
然后重新启动
- 启动成功访问页面 http://ip:8848/nacos/
默认账号密码: nacos nacos
二、使用nacos
Nacos Spring Cloud 快速开始
- 添加依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
注意:版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本。版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本,版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版本。
- 在 bootstrap.properties 中配置 Nacos server 的地址和应用名
#nacos 配置
spring.application.name=nacos-config-client
#配置文件类型[TEXT,JSON,XML,YAML,HTML,Properties]
spring.cloud.nacos.config.file-extension=yml
spring.cloud.nacos.config.server-addr=192.168.26.115:8848
spring.cloud.nacos.config.namespace=public
# 配置分组,当前的业务基本选择为某些的GROUP,可以基于业务来划分不同的分组.
#spring.cloud.nacos.config.group=DEFAULT_GROUP
# 默认选择的配置环境,当前把环境划分为4套, dev[开发环境],test[测试环境],pre[预发环境],prod[生产环境]
#spring.profiles.active=dev
在 Nacos Spring Cloud 中,dataId 的完整格式如下:
${spring.application.name}-${spring.profile.active}.${file-extension}
- prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
- spring.profile.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当 spring.profile.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 {file-extension}
- file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。
版本对应关系参考:版本说明 Wiki
nacos关闭客户端心跳日志:
客户端依赖nacos版本:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
客户端控制台一直打印:
INFO 17770 --- [131_32480-ta404] c.a.n.client.config.impl.ClientWorker : get changedGroupKeys:[]
INFO 17770 --- [131_32480-ta404] c.a.n.client.config.impl.ClientWorker : get changedGroupKeys:[]
关闭客户端心跳日志:
logging:
level:
com:
alibaba:
nacos:
client: error
nacos配置:
nacos配置可分为:shared、extConfig、ApplicationConfig(加载顺序shared、extConfig、ApplicationConfig, 后加载的配置可覆盖先加载的配置)
源码:
NacosPropertySourceLocator类:
loadSharedConfiguration(composite);
loadExtConfiguration(composite);
loadApplicationConfiguration(composite, dataIdPrefix, this.nacosConfigProperties, env);
spring:
cloud:
nacos:
config:
file-extension: yml
server-addr: 192.168.26.131:31971
prefix: test
spring:
profiles:
active: dev,mybatis,cas,platform
默认读取: test test-dev.yml test-mybatis.yml test-cas.yml test-platform.yml
后读取的覆盖先读取的,test-platform.yml(优先级最高)的配置默认覆盖之前的
配置中心的配置>启动参数>项目里的配置
配置写法:
spring:
profiles:
active: dev,mybatis
application:
name: demo
cloud:
nacos:
config:
file-extension: yml
server-addr: 127.0.0.1:8848
namespace: public
enableRemoteSyncConfig: true
shared-dataids: shareconfig1.yml,shareconfig2.yml
refreshable-dataids: shareconfig1.yml,shareconfig2.yml
extConfig:
- dataId: example.yaml
refresh: true
配置自动更新
- 通过 Spring Cloud 原生注解 @RefreshScope 实现配置自动更新
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
@Value("${useLocalCache:false}")
private boolean useLocalCache;
@RequestMapping("/get")
public boolean get() {
return useLocalCache;
}
}
- java 配置类实现自动刷新:
//@RefreshScope 配置bean不用加这个注解
@Component
@ConfigurationProperties(prefix = "ta")
public class TaAudit1Properties {
/**
* 上传开关
*/
private boolean uploadSwitch = false;
/**
* 上传扩展
*/
// @Value("${explore}") 配置bean不用加这个注解
private String explore = "base";
public String getExplore() {
return explore;
}
public void setExplore(String explore) {
System.out.println("进入set方法~~~~~");
this.explore = explore;
}
public boolean isUploadSwitch() {
return uploadSwitch;
}
public void setUploadSwitch(boolean uploadSwitch) {
this.uploadSwitch = uploadSwitch;
}
}
总结:
其他类中使用@Value 需要添加@RefreshScope才能动态修改配置
Java 配置bean:去掉@RefreshScope和@Value ,则修改配置时就能修改环境,然后走set 方法(正确的用法)
Java配置bean:只要加上@RefreshScope,则修改配置时,修改了环境但是没走set方法,反而在调用的时候get的时候才走set 方法(即调用get 的时候才刷新bean)只加@value没问题
nacos界面权限控制没有效果 需要在nacos 安装目录下的application.properties中将配置设为true:nacos.core.auth.enabled=true
nacos原理:
- 首先更新环境中配置
2.将所有java配置bean 销毁后重新初始化
Map<String, Object> beanMap = applicationContext.getBeansWithAnnotation(ConfigurationProperties.class);
// 刷新bean的配置
if (beanMap != null){
for (Map.Entry<String, Object> entry : beanMap.entrySet()) {
String beanName = entry.getKey();
Object bean = entry.getValue();
rebind(beanName, bean);
}
}
public boolean rebind(String beanName, Object bean) {
if (this.applicationContext != null) {
try {
if (AopUtils.isAopProxy(bean)) {
bean = ProxyUtils.getTargetObject(bean);
}
if (bean != null) {
this.applicationContext.getAutowireCapableBeanFactory().destroyBean(bean);
this.applicationContext.getAutowireCapableBeanFactory().initializeBean(bean, beanName);
return true;
}
} catch (RuntimeException var3) {
if (log.isDebugEnabled()) {
log.debug("更新bean失败", var3);
}
throw new AppException("更新bean失败");
} catch (Exception var4) {
if (log.isDebugEnabled()) {
log.debug("Cannot rebind to {}", beanName, var4);
}
throw new AppException("Cannot rebind to " + beanName);
}
}
return false;
}
三、nacos源码开发:
nacos使用外嵌数据库mysql,需在配置文件中配置如下:且必须配置spring.datasource.platform=mysql ,否则还是用内嵌数据库(Derby)
##mysql datasource
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456
nacos客户端如何获取配置: nacos客户端维护了一个长轮询的任务,定时去拉取发生变更的配置信息,然后将最新的数据推送给 Listener 的持有者。
考虑到服务端故障的问题,客户端将最新数据获取后会保存在本地的 snapshot 文件中,以后会优先从文件中获取配置信息的值。
nacos客户端读取配置: 获取配置的优先级依次为:本地配置 -> 服务端获取的配置 -> Snapshot保存的配置。
源码:
NacosConfigService -->getConfigInner()
/Users/zj/nacos/config/fixed-127.0.0.1_8848-namespace1_nacos/snapshot-tenant/namespace1/DEFAULT_GROUP/example.yaml
nacos存在的问题:
启动报错org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1
检查yml文件中包含中文,去掉再启动就好了
或者 解决方案:
设置JVM参数 -Dfile.encoding=utf-8即可,java -Dfile.encoding=utf-8 -jar
开启这个权限会存在很多问题:
nacos.core.auth.enabled=true
- 界面控制不当,没有权限的人也能看到全部命名空间的问题
nacos打包命令
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
nacos启动类
nacos-console模块下