nacos 1.2.1 版本 从安装到使用配置中心

487 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、安装nacos

  1. 下载nacos 官网:github.com/alibaba/nac…

我是安装到linux,则下载****.tar.gz

  1. 解压 下载完成的nacos-server-1.2.1.tar.gz进行解压

解压命令: tar zxvf nacos-server-1.2.1.tar.gz

  1. 启动nacos 解压后进入到bin目录,然后执行命令:

sh startup.sh -m standalone 该方式启动,是单机模式启动。

  1. 报错 若发现启动完成报错:java.io.FileNotFoundException: /data/nacos/conf/cluster.conf (No such file or directory)

简单粗暴的解决方式:

  1. vim startup.sh
  2. 将脚本中的 if [ "MODE"=="standalone"];改为if["{MODE}" == "standalone" ]; 改为if [ "{MODE}" = "standalone" ]; 即可

然后重新启动

  1. 启动成功访问页面 http://ip:8848/nacos/

默认账号密码: nacos nacos

二、使用nacos

Nacos Spring Cloud 快速开始

  1. 添加依赖:
<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 版本。

  1. 在 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 的拼接格式变成 prefix.{prefix}.{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

配置自动更新

  1. 通过 Spring Cloud 原生注解 @RefreshScope 实现配置自动更新
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
 
    @Value("${useLocalCache:false}")
    private boolean useLocalCache;
 
    @RequestMapping("/get")
    public boolean get() {
        return useLocalCache;
    }
}
  1. 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原理:

  1. 首先更新环境中配置

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

  1. 界面控制不当,没有权限的人也能看到全部命名空间的问题

nacos打包命令

mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U

nacos启动类

nacos-console模块下