一:Nacos服务端的使用
1.安装包下载
首先到nacos的官网下载nacos的服务端,由于,由于我使用的Spirng Cloud Alibaba的版本是2.2.5.RELEASE,根据上一篇中Spring Cloud Alibaba专题–2.2.5.RELEASE–Spring Cloud Alibaba介绍(三)–组件版本关系,应该下载1.4.1版本的nacos服务端
2.启动Nacos服务端
cd到nacos的bin目录下,启动命令(standalone代表着单机模式运行,非集群模式):
sh startup.sh -m standalone
关闭命令
sh shutdown.sh
其他环境如window的命令参考nacos官网-快速开始
3.Nacos自带的可视化界面的使用
默认地址localhost:8848/nacos,通过浏览器打开
输入默认的用户名(nacos)和密码(nacos)
这个nacos-config.properties是我自己测试增加的配置,内容如下
二:Spring Cloud Alibaba集成Nacos作为配置中心
1.引入版本控制pom
<properties>
<java.version>1.8</java.version>
<spring-cloud-alibaba.version>2.2.5.RELEASE</spring-cloud-alibaba.version>
<dubbo.version>2.7.8</dubbo.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<!--spring-boot dependencies pom 依赖包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring-cloud-alibaba dependencies pom 依赖包-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring-cloud dependencies pom 依赖包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencyManagement>
2.引入Nacos配置中心相关依赖
<dependencies>
<!--spring-cloud-alibaba nacos配置中心驱动包-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--spring-boot 监控端点包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--spring-mvc 依赖包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!--spring-test 单元测试依赖包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
3.系统配置
按照官方文档要求,Nacos的某些配置只能在bootstrap配置文件(Spring的父上下文默认的配置文件)中才能生效,不能配置在application配置文件中(spring上下文默认配置文件),当然,至于文件格式的优先级,仍然是properties的优先级大于yaml的优先级,这里我使用的properties
bootstrap.properties
#nacos配置中心地址
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
#项目名称
spring.application.name=nacos-demo
4.简单代码测试
(1)Controller代码
package com.example.nacos.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
@Value("${test.name}")
private String name;
@Value("${test.age:0}")
private Integer age;
@RequestMapping("/get")
public String get() {
return "name:".concat(name).concat(" age:").concat(String.valueOf(age));
}
}
(2)启动服务
报错了,这里的启动日志中有一个关键信息:
可以看到,Nacos会根据定义的${spring.application.name}去找对应的配置,这里我加了profile是dev,在说Nacos的配置查找的时候,这里说一个概念
(3)匹配概念
-
优先级匹配
优先级高的优先加载,但是如果没有对应的属性,按照优先级向下排,谁有这个属性用谁的 -
单一(精准)匹配
对于使用了某个配置,其他配置均不生效,即使自己没有,别人的也不生效
(4)Nacos的配置文件的标准配置
上述的Nacos的配置文件的配置(标准配置)匹配遵从优先级匹配,
默认加载配置的公式为:
${prefix}-${spring.profiles.active}.${file-extension}
其中
- prefix默认取值为spring.application,name,当然也可以指定这一配置spring.cloud.nacos.config.prefix
- spring.profiles.active指定的profiles环境,目前我指定了dev
- file-extension 配置文件后缀 默认properties
该公式存在以下几种配置:
以a.properties 为例
其中会加载三种配置文件
1.配置了spring的profies且严格匹配表达式的 比如dev环境,如a-dev.properties
2.未匹配${spring.profiles.active},如a.properties
3.仅仅匹配 ${prefix}这一项的 如a
其中优先级为 1>2>3
在nacos的public命名空间,配置的名称为nacos-config.properties现在的配置是:
spring.application.name=nacos-demo
所以加载的文件名称不匹配,这里把${prefix}直接指定,不修改spring.application,name的配置,增加配置:
#配置文件前缀 配置这个后 将不再使用spring.application.name作为${prefix}的取值
spring.cloud.nacos.config.prefix=nacos-config
(2)再次重启测试
启动成功,访问测试下
没有问题
三:环境隔离
实际的工作场景中,我们的系统是存在多个环境的,那么多环境配置文件隔离nacos如何实现呢?
1.Nacos的数据模型
Nacos 数据模型 Key 由三元组唯一确定, Namespace默认是空串,公共命名空间(public),分组默认是 DEFAULT_GROUP
刚刚我们讨论的配置文件的有限级仅仅只是最后一个层面Service/DataId这个层面的
2.使用Service/DataId标准配置加载优先级实现环境隔离
根据配置文件加载公式,当指定的profile,优先匹配带有-${profile}的配置,可以通过这种方式,实现环境隔离。比如我们存在dev和test两个环境
nacos-config.properties
nacos-config-dev.properties
nacos-config-test.properties
当指定了profile为dev时,加载nacos-config-dev.properties,其次加载nacos-config.properties,这种配置加载的优先级机制与Spring的application配置加载方式如出一辙
但是毕竟Spring的配置文件是在每个项目中的,存在着物理隔离(不同文件夹),如果使用上述的方式实现环境隔离,所有项目的某环境的配置全部都在同一个命名空间下,这种方式显然是不优雅的
3.使用namespace实现环境隔离
这也是nacos官方推荐的环境隔离的方案
(1)添加命名空间
这里添加了三个命名空间,dev,test以及prep,可以看到,除了public(保留空间)外,其他的自定义空间都是拥有id的。
这个时候配置列表中就出现了相关的命名空间
(2)测试dev环境的文件配置
a.克隆一个配置到dev环境
由于文件自带的后缀名可能与真正选择的文件类型不匹配,这里选择不再在配置中添加文件配置的后缀,方便后面properties修改yaml
b.修改test.name为‘dev-name’
c.代码中指定namespace
这里需要注意,namespace的指定使用的是id而不是名称,上面dev空间的id为7cce593a-d787-4bf4-b599-03f6863cfbea
#指定命名空间
spring.cloud.nacos.config.namespace=7cce593a-d787-4bf4-b599-03f6863cfbea
d.访问测试
成功请求到dev命名空间下的配置
4.基于namespace环境隔离切换问题
Spring的环境隔离指定profile即可,但是配置的环境隔离使用的是Nacos的namespace的id,后面切换环境的时候还要手动更改id,这个就比较烦,能不能保持Spring环境切换的习惯,更改默认环境呢?
(1)配置maven的过滤器
<profiles>
<profile>
<id>开发环境</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<profileActive>dev</profileActive>
</properties>
</profile>
<profile>
<id>测试环境</id>
<properties>
<profileActive>test</profileActive>
</properties>
</profile>
<profile>
<id>预发环境</id>
<properties>
<profileActive>prep</profileActive>
</properties>
</profile>
<profile>
<id>生产环境</id>
<properties>
<profileActive>prod</profileActive>
</properties>
</profile>
</profiles>
<build>
<filters> <!-- 指定使用的filter文件,根据profile设置过滤文件 -->
<filter>src/main/resources/filter/${profileActive}.properties</filter>
</filters>
<!--开启资源过滤:将resources中配置文件的变量利用profile进行替换-->
<resources>
<resource>
<directory>src/main/resources</directory>
<!--允许进行资源过滤-->
<filtering>true</filtering>
<excludes>
<exclude>filter</exclude>
</excludes>
</resource>
</resources>
</build>
这里包含三个部分部分内容
- profiles标签:定义maven中指定环境的变量名及变量值,变量名为profileActive,变量名分别是dev、test、prep、prod
- filters标签:指定filter的地址,这里定义在src/main/resources/filter/${profileActive}.properties
- resources标签:指定被替换的文件所在的目录
(2)添加maven环境配置
dev.properties配置
#nacos配置地址
maven.nacos.serverAddr=127.0.0.1:8848
#nacos命名空间
maven.nacos.namespace=7cce593a-d787-4bf4-b599-03f6863cfbea
test.properties配置
#nacos配置地址
maven.nacos.serverAddr=127.0.0.1:8848
#nacos命名空间
maven.nacos.namespace=bba1c4dd-8086-4341-ae6a-69692b4bfb62
注意这里的namespace更换为test命名空间的id了
(3)引用maven环境配置
#nacos配置中心
spring.cloud.nacos.config.server-addr=${maven.nacos.serverAddr}
#项目名称 ${prefix}默认取值,当存在spring.cloud.nacos.config.prefix后,则不会使用此配置值
spring.application.name=nacos-demo
#配置文件前缀 配置这个后 将不再使用spring.application.name作为${prefix}的取值
spring.cloud.nacos.config.prefix=nacos-config
#配置文件类型 默认就是properties
spring.cloud.nacos.config.group=DEFAULT_GROUP
#配置文件类型 默认就是properties
spring.cloud.nacos.config.file-extension=properties
#命名空间
spring.cloud.nacos.config.namespace=${maven.nacos.namespace}
(4)环境切换测试
使用nacos界面,再次克隆一个配置到test命名空间下,修改test.name=test-name
指定profile为dev(这里使用的是idea的插件,其他指定方式自行探索)
启动并访问
指定profile为test
启动并访问
四:共享配置及扩展配置
1.共享配置
事实上,我们还存在共享配置的场景。比如系统接入了阿里云,需要有阿里云相关的配置项,有很多的子系统都要使用这个配置,每个子系统的配置中都写一份并不优雅,后期更换了阿里云的配置,还要一个一个找并替换。既然是共享配置,强调的是多个系统都会使用的配置,而nacos支持这种共享配置
spring.cloud.nacos.config.shared-configs[0].data-id=base-config
spring.cloud.nacos.config.shared-configs[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.shared-configs[0].refresh=true
这样就指定了共享的配置文件,我们在nacos中添加base-config即可被加载到
注意点:
- 共享配置不存在领域模型中Service/DataId中的公式优先级匹配的概念,仅根据data-id匹配
- 多个共享配置使用下标序号隔开,序号越大优先级越高
2.扩展配置
针对单个项目,配置文件的内容包含各种各样的配置,单个文件配置过几百行都不夸张,这样单个文件的可读性就大大降低了,且后面很不方便查找。为了让配置更加清晰,希望按照业务或者模块的角度去把配置拆成多个配置文件,使得每个配置文件就几十行。使用标准的公式优先级匹配的方式虽然能加载多个配置文件,但是配置文件并不能更改名称,无法达到目的,nacos提供了扩展配置相关的配置项
spring.cloud.nacos.config.extension-configs[0].data-id=common-config
spring.cloud.nacos.config.extension-configs[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.extension-configs[0].refresh=true
和共享配置一样
- 扩展配置不存在领域模型中Service/DataId中的公式优先级匹配的概念,仅根据data-id匹配
- 多个扩展配置使用下标序号隔开,序号越大优先级越高
五.Nacos所有配置的优先级整理
数据模型中提到了namespace,group以及service/dataId,其中namespace和group均是使用单一(精准)匹配,这里就不说了,但看service/dataId这一层的匹配
从配置方式上说存在三种方式:
1.标准配置
即使用spring.cloud.nacos.config.prefix,这种方式中存在三中匹配已经在上文中Nacos的配置文件的标准匹配提到了
2.扩展配置
扩展配置的优先级仅次于标准配置,其中内部的扩展配置,序号越大,优先级越高
3.共享配置
三种方式中优先级最低的方式,其中内部的共享配置,序号越大,优先级越高
所以整个匹配的优先级整理个图方便理解:
六.Nacos的配置监控端点的使用
监控端点(Actuator)本身是Spring Boot提供的能力,具体见官方文档Nacos扩展了自己的监控端点,通过暴露Spring Boot的监控端点即可
1.添加Actuator依赖
<!--spring-boot 监控端点包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
因为在dependencyManagement中已经加入了Spring Boot dependencies pom 依赖包,这里不需要指定版本(如果没有加入则需要指定版本)
2.开启端点
配置文件中添加配置
management.endpoints.web.exposure.include=*
这里开启了所有端点,也可以自定义开启那些端点
3.配置监控端点使用的用途
监控端点是通过项目内嵌服务器暴露的,所以host及port与项目一致,这里是localhost:8080,监控端点的默认context path(上下文路径)为/actuator,在浏览器输入地址localhost:8080/actuator
点击nacosconfig端点地址
这里包含了本机连接Nacos的配置中心相关的信息,以此来确认当前服务器的配置,可以辅助排查因本机配置问题导致远程配置拉取不正确相关的问题
七.其他
nacos还支持秒级的配置刷新,历史版本记录,配置回滚,灰度发布等功能,由于篇幅有限,且应用层面比较简单,这里就不直接测试了。但是这些能力的源码层面还是值得了解的,后面会针对该部分补充源码分析