Nacos-配置管理
目录4 Nacos 配置管理基础应用
4.1 Nacos 配置管理模型
对于Nacos配置管理,通过Namespace、group、Data ID能够定位到一个配置集。
配置集 (Data ID)
在系统中,一个配置文件通常就是一个配置集,一个配置集可以包含了系统的各种配置信息,例如,一个配置集可能包含了数据源、线程池、日志级别等配置项。每个配置集都可以定义一个有意义的名称,就是配置集的ID即DataID。
配置项
配置集中包含的一个个配置内容就是配置项。它代表一个具体的可配置的参数与其值域,通常以 key=value 的形式存在。例如我们常配置系统的日志输出级别(logLevel=INFO|WARN|ERROR) 就是一个配置项。
配置分组 (Group)
配置分组是对配置集进行分组,通过一个有意义的字符串(如 Buy 或 Trade )来表示,不同的配置分组下可以有相同的配置集(Data ID)。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:可用于区分不同的项目或应用,例如:学生管理系统的配置集可以定义一个group为:STUDENT_GROUP。
命名空间 (Namespace)
命名空间(namespace)可用于进行不同环境的配置隔离。例如可以隔离开发环境、测试环境和生产环境,因为它们的配置可能各不相同,或者是隔离不同的用户,不同的开发人员使用同一个nacos管理各自的配置,可通过namespace隔离。不同的命名空间下,可以存在相同名称的配置分组(Group) 或 配置集。
最佳实践
Nacos抽象定义了Namespace、Group、Data ID的概念,具体这几个概念代表什么,取决于我们把它们看成什么,这里推荐给大家一种用法,如下图:
Namespace:代表不同环境,如开发、测试、生产环境。
Group:代表某项目,如XX医疗项目、XX电商项目
DataId:每个项目下往往有若干个工程,每个配置集(DataId)是一个工程的主配置文件
获取某配置集的代码:
获取配置集需要指定:
1、nacos服务地址,必须指定
2、namespace,如不指定默认public
3、group,如不指定默认 DEFAULT_GROUP
4、dataId,必须指定
代码如下:
看懂即可不用运行。
4.2 命名空间管理
4.2.1namespace 隔离设计
namespace 的设计是 nacos 基于此做多环境以及多租户(多个用户共同使用nacos)数据(配置和服务)隔离的。
- 从一个租户(用户)的角度来看,如果有多套不同的环境,那么这个时候可以根据指定的环境来创建不同的namespce,以此来实现多环境的隔离。例如,你可能有开发,测试和生产三个不同的环境,那么使用一套nacos 集群可以分别建以下三个不同的 namespace。如下图所示:
-
从多个租户(用户)的角度来看,每个租户(用户)可能会有自己的 namespace,每个租户(用户)的配置数据以及注册的服务数据都会归属到自己的 namespace 下,以此来实现多租户间的数据隔离。例如超级管理员分配了三个租户,分别为张三、李四和王五。分配好了之后,各租户用自己的账户名和密码登录后,创建自己的命名
空间。如下图所示:
4.2.2 命名空间管理
前面已经介绍过,命名空间(Namespace)是用于隔离多个环境的(如开发、测试、生产),而每个应用在不同环境的同一个配置(如数据库数据源)的值是不一样的。因此,我们应针对企业项目实际研发流程、环境进行规划。如某软件公司拥有开发、测试、生产三套环境,那么我们应该针对这三个环境分别建立三个namespace。
建立好所有namespace后,在配置管理与服务管理模块下所有页面,都会包含用于切换namespace(环境)的tab按钮,如下图:
如果您在编写程序获取配置集过程中没有感知到这个参数的输入,那么 nacos 统一会使用一个默认的 namespace作为输入,nacos confifig 会使用一个空字符串作为默认的参数来初始化,对应界面上就是public命名空间。
Note: namesace 为 public 是 nacos 的一个保留空间,如果您需要创建自己的 namespace,不要和 public重名,以一个实际业务场景有具体语义的名字来命名,以免带来字面上不容易区分自己是哪一个namespace。
Note:在编写程序获取配置集时,指定的namespace参数一定要填写命名空间 ID,而不是名称
运行下边的程序测试新建的命名空间:
注意:namespace的值根据自己的环境确定。
// 初始化配置服务,
String serverAddr = "127.0.0.1:8848";
String namespace = "ee247dde‐d838‐425c‐b371‐029dab26232f"; //开发环境
String group = "DEFAULT_GROUP"; //默认组
String dataId = "nacos‐simple‐demo.yaml";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
properties.put("namespace", namespace);
ConfigService configService = NacosFactory.createConfigService(properties);
//获取配置,并输出控制台
String content = configService.getConfig(dataId, group, 5000);
System.out.println(content);
4.3 配置管理
Nacos支持基于Namespace和Group的配置分组管理,以便用户更灵活的根据自己的需要按照环境或者应用、模块等分组管理微服务的大量配置,在配置管理中主要提供了配置历史版本、回滚、订阅者查询等核心管理能力。
4.2.1 配置列表
点击Nacos控制台的 配置管理->配置列表 菜单,即可看到以下界面展示:
界面中展示了不同namespace下的配置集列表,可点击左上角的不同namespace进行切换。右上角“+"号或点击某配置集后的 编辑 按钮可进入配置集编辑器。
多配置格式编辑器
Nacos支持 YAML、Properties、TEXT、JSON、XML、HTML 等常见配置格式在线编辑、语法高亮、格式校验,帮助用户高效编辑的同时大幅降低格式错误带来的风险。Nacos支持配置标签的能力,帮助用户更好、更灵活的做到基于标签的配置分类及管理。同时支持用户对配置及其变更进行描述,方面多人或者跨团队协作管理配置。
配置集导出
勾选若干配置集,点击 导出选中的配置 ,可获得一个压缩包:
5 Nacos****配置管理应用于分布式系统
5.1.1 单体架构
Web应用程序发展的早期,大部分web工程师将所有的功能模块打包到一起并放在一个web容器中运行,所有功能模块使用同一个数据库,同时,它还提供API或者UI访问的web模块等。
尽管也是模块化逻辑,但是最终它还是会打包并部署为单体式应用,这种将所有功能都部署在一个web容器中运行
的系统就叫做单体架构(也叫:巨石型应用)。
单体架构有很多好处:
开发效率高:模块之间交互采用本地方法调用,并节省微服务之间的交互讨论时间与开发成本。
容易测试:IDE都是为开发单个应用设计的、容易测试——在本地就可以启动完整的系统。
容易部署:运维成本小,直接打包为一个完整的包,拷贝到web容器的某个目录下即可运行。
但是,上述的好处是有条件的,它适用于小型简单应用,对于大规模的复杂应用,就会展现出来以下的不足:
复杂性逐渐变高,可维护性逐渐变差 :所有业务模块部署在一起,复杂度越来越高,修改时牵一发动全身。
版本迭代速度逐渐变慢:修改一个地方就要将整个应用全部编译、部署、启动时间过长、回归测试周期过长。
阻碍技术创新:若更新技术框架,除非你愿意将系统全部重写,无法实现部分技术更新。
无法按需伸缩:通过冗余部署完整应用的方式来实现水平扩展,无法针对某业务按需伸缩。
5.1.2 微服务
许多大型公司,通过采用微服务架构解决了上述问题。其思路不是开发一个巨大的单体式的应用,而是将应用分解
为小的、互相连接的微服务。
一个微服务一般完成某个特定的功能,比如订单服务、用户服务等等。每一个微服务都是完整应用,都有自己的业
务逻辑和数据库。一些微服务还会发布API给其它微服务和应用客户端使用。
比如,根据前面描述系统可能的分解如下:
每一个业务模块都使用独立的服务完成,这种微服务架构模式也影响了应用和数据库之间的关系,不像传统多个业
务模块共享一个数据库,微服务架构每个服务都有自己的数据库。
微服务架构的好处:
分而治之,职责单一;易于开发、理解和维护、方便团队的拆分和管理
可伸缩;能够单独的对指定的服务进行伸缩
局部容易修改,容易替换,容易部署,有利于持续集成和快速迭代
不会受限于任何技术栈
5.2 分布式应用配置管理
下图展示了如何通过Nacos集中管理多个服务的配置:
用户通过Nacos Server的控制台集中对多个服务的配置进行管理。
各服务统一从Nacos Server中获取各自的配置,并监听配置的变化。
5.2.1 发布配置
首先在nacos发布配置,我们规划了两个服务service1、service2,并且想对这两个服务的配置进行集中维护。
浏览器访问 http://127.0.0.1:8848/nacos ,打开nacos控制台,并点击菜单配置管理 -> 配置列表:
在Nacos添加如下的配置:
service1
Namespace: c67e4a97‐a698‐4d6d‐9bb1‐cfac5f5b51c4 #开发环境
Data ID: service1.yaml
Group : TEST_GROUP
配置格式: YAML
配置内容: common:
name: service1 config
service2
Namespace: c67e4a97‐a698‐4d6d‐9bb1‐cfac5f5b51c4 #开发环境
Data ID: service2.yaml
Group : TEST_GROUP
配置格式: YAML
配置内容: common:
name: service2 config
5.2.2 创建父工程
<?xml version="1.0" encoding="UTF‐8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema‐instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven‐4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima.nacos</groupId>
<artifactId>nacos‐config</artifactId>
<version>1.0‐SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF‐8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF‐8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐alibaba‐dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐maven‐plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
5.2.3 微服务 service1 配置
本小节,我们将演示如何使用 Spring Cloud Alibaba Nacos Confifig在Spring Cloud应用中集成Nacos,通过Spring cloud原生方式快捷的获取配置内容。
Spring Cloud是什么:
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,集成最多的组件要属Netflflix公司,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
Spring Cloud Alibaba Nacos Confifig是什么:
Spring Cloud Alibaba Nacos Discovery是Spring Cloud Alibaba的子项目,而Spring Cloud Alibaba是阿里巴巴公司提供的开源的基于Spring cloud的微服务套件合集,它致力于提供微服务开发的一站式解决方案,可以理解为spring cloud是一套微服务开发的 标准 ,spring cloud alibaba与spring cloud Netflflix是实现。使用 Spring Cloud Alibaba方案,开发者只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。
由于Nacos是阿里的中间件,因此,若开发Spring cloud微服务应用,使用Spring Cloud Alibaba Nacos Confifig来集成Nacos的配置管理功能是比较明智的选择。
-
( 1 )新建项目 service1
首先新增一个名为service1工程,并添加group ID 为 com.alibaba.cloud 和 artifact ID 为 spring-cloudstarter-alibaba-nacos-config 的 starter。
<parent> <artifactId>nacos‐config</artifactId> <groupId>com.itheima.nacos</groupId> <version>1.0‐SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>service1</artifactId> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring‐cloud‐starter‐alibaba‐nacos‐config</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring‐boot‐starter‐web</artifactId> </dependency> </dependencies> 北京市昌
-
( 2 ) bootstrap.yml 配置
一般来说,spring boot的配置将在application.yml(也可以是application.properties)文件中编写, 由于使用外部配置中心,必须将原先的application.yml重命名为bootstrap.yml,bootstrap.yml如下所示:spring.cloud.nacos.confifig.server-addr 指定了Nacos Server的网络地址和端口号。
以上配置文件说明该应用将从地址为127.0.0.1:8848配置中心获取配置,通过以下信息定位配置集:
namespace:c67e4a97‐a698‐4d6d‐9bb1‐cfac5f5b51c4 # 开发环境
group:TEST_GROUP # 测试组
Data Id:service1.yaml
Note:spring-cloud-starter-alibaba-nacos-confifig 在加载配置的时候,加载了以 dataid 为${spring.application.name}.${file-extension:properties} 的基础配置。对应以上的配置,它会去nacos server中加载data id为service1.yaml的配置集。
Note: 若没有指定spring.cloud.nacos.confifig.group配置,则默认为DEFAULT_GROUP。
- ( 3 )启动配置客户端
新增Spring Boot 启动类,并增加获取配置的web访问端点/confifigs,通过标准的spring @Value 方式。
package com.itheima.nacos;
@SpringBootApplication
@RestController
public class Service1Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Service1Bootstrap.class, args);
}
@Value("${common.name}")
private String config1;
@GetMapping(value = "/configs")
public String getConfigs(){
return config1;
}
}
5.2.4 微服务 service2 配置
service2的创建流程与service1一致:
需要注意的是spring boot 启动端口要避免重复,spring.application.name为service2。
分别启动service1和service2项目,并分别访问 /confifigs进行测试,不同项目能够获取各自的配置内容。
5.2.3 支持配置的动态更新
基于上面快速上手的例子,若要实现配置的动态更新,只需要进行如下改造:
我们通过nacos控制台更新common.name的配置值,再次访问web端点/confifigs,发现应用程序能够获取到最新的配置值,说明spring-cloud-starter-alibaba-nacos-confifig 支持配置的动态更新。
Note 可以通过配置spring.cloud.nacos.confifig.refresh.enabled=false来关闭动态刷新
5.2.4 自定义 namespace 与 group 配置
支持自定义 namespace 的配置
在没有明确指定 ${spring.cloud.nacos.config.namespace} 配置的情况下, 默认使用的是 Nacos 上 Public 这个namespace。如果需要使用自定义的命名空间,可以通过以下配置来实现:
Note:该配置必须放在 bootstrap.yml文件中。此外 spring.cloud.nacos.config.namespace 的值是 namespace对应的 id,id 值可以在 Nacos 的控制台获取。并且在添加配置时注意不要选择其他的 namespae,否则将会导致读取不到正确的配置。
支持自定义 Group 的配置
在没有明确指定 ${spring.cloud.nacos.config.group} 配置的情况下, 默认使用的是 DEFAULT_GROUP 。如果需要自定义自己的 Group,可以通过以下配置来实现
Note:该配置必须放在 bootstrap.properties 文件中。并且在添加配置时 Group 的值一定要和spring.cloud.nacos.config.group 的配置值一致。
5.2.5 自定义扩展的 Data Id 配置
Spring Cloud Alibaba Nacos Confifig可支持自定义 Data Id 的配置。 一个完整的配置案例如下所示:下边我们在service2微服务下配置扩展。
可以看到:
-
通过 spring.cloud.nacos.config.ext-config[n].data-id 的配置方式来支持多个 Data Id 的配置。
-
通过 spring.cloud.nacos.config.ext-config[n].group 的配置方式自定义 Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUP。
-
通过 spring.cloud.nacos.config.ext-config[n].refresh 的配置方式来控制该 Data Id 在配置变更时,是否支持应用中可动态刷新, 感知到最新的配置值。默认是不支持的
Note : spring.cloud.nacos.config.ext-config[n].data-id 的值必须带文件扩展名,文件扩展名既可支持properties,又可以支持 yaml/yml。 此时 spring.cloud.nacos.config.file-extension 的配置对自定义扩展配置的 Data Id 文件扩展名没有影响。
通过自定义扩展的 Data Id 配置,既可以解决多个应用间配置共享的问题,又可以支持一个应用有多个配置文件。
测试:
配置ext-confifig-common01.properties:
配置ext-confifig-common02.properties
配置ext-confifig-common03.properties
编写测试代码:
@GetMapping(value = "/configs2")
public String getConfigs2(){
String name = applicationContext.getEnvironment().getProperty("common.name");
String age = applicationContext.getEnvironment().getProperty("common.age");
String address = applicationContext.getEnvironment().getProperty("common.address");
String birthday= applicationContext.getEnvironment().getProperty("common.birthday");
String fullname = applicationContext.getEnvironment().getProperty("common.fullname");
return name+"+"+ age+"+"+address+"+"+ birthday+"+"+ fullname;
}
重启应用,访问http://localhost:56011/confifigs2,观察配置是否成功获取。
输出:
service2 config+12+beijing+1990‐1‐1+zhangsansanff
5.2.6 自定义共享 Data Id 配置
为了更加清晰的在多个应用间配置共享的 Data Id ,你可以通过以下的方式来配置:
可以看到:
通过 spring.cloud.nacos.config.shared-dataids 来支持多个共享 Data Id 的配置,多个之间用逗号隔开。
通过 spring.cloud.nacos.config.refreshable-dataids 来支持哪些共享配置的 Data Id 在配置变化时,应用中是否可动态刷新, 感知到最新的配置值,多个 Data Id 之间用逗号隔开。如果没有明确配置,默认情况下所有共享配置的 Data Id 都不支持动态刷新。
Note:通过 spring.cloud.nacos.config.shared-dataids 来支持多个共享配置的 Data Id 时, 多个共享配置间的一个优先级的关系我们约定:按照配置出现的先后顺序,即后面的优先级要高于前面。
Note:通过 spring.cloud.nacos.config.shared-dataids 来配置时,Data Id 必须带文件扩展名,文件扩展名既可支持 properties,也可以支持 yaml/yml。 此时 spring.cloud.nacos.config.file-extension 的配置对自定义扩展配置的 Data Id 文件扩展名没有影响。
Note: spring.cloud.nacos.config.refreshable-dataids 给出哪些需要支持动态刷新时,Data Id 的值也必须明确给出文件扩展名。
测试输出:
service2 config+12+beijing+null+null
为什么后边两个值为null?
共享DataId的配置使用默认的group即DEFAULT_GROUP,ext-confifig-common02.properties不属于DEFAULT_GROUP。共享DataId的配置相比扩展的 Data Id 配置,它把group固定为DEFAULT_GROUP,建议使用扩展的 Data Id 配置,因为扩展的 Data Id 配置也可以实现共享DataId配置。
5.2.7 配置的优先级
Spring Cloud Alibaba Nacos Confifig 目前提供了三种配置能力从 Nacos 拉取相关的配置。
-
A: 通过 spring.cloud.nacos.config.shared-dataids 支持多个共享 Data Id 的配置
-
B: 通过 spring.cloud.nacos.config.ext-config[n].data-id 的方式支持多个扩展 Data Id 的配置,多个Data Id 同时配置时,他的优先级关系是 spring.cloud.nacos.config.ext-config[n].data-id 其中 n 的值越大,优先级越高。
-
C: 通过内部相关规则(应用名、扩展名 )自动生成相关的 Data Id 配置
当三种方式共同使用时,他们的一个优先级关系是:C > B >A
测试,屏蔽共享dataId,放开ext-confifig,如下:
修改ext-confifig-common03.properties:
输出:
service2 config aaa+15+beijing+1990‐1‐1+zhangsansanff
通过测试发现多个 Data Id 同时配置时,他的优先级关系是 spring.cloud.nacos.
config.ext-config[n].data-id其中 n 的值越大,优先级越高。
修改:service1.yaml
输出:
service2 config aaa+25+beijing+1990‐1‐1+zhangsansanff
通过测试发现:B和C同时存在,C优先级高。
5.3 Nacos****集群部署
5.3.1 集群部署
3个或3个以上Nacos节点才能构成集群
(1)安装3个以上Nacos
我们可以复制之前已经解压好的nacos文件夹,分别命名为nacos、nacos1、nacos2
(2)配置集群配置文件
在所有nacos目录的conf目录下,有文件 cluster.conf.example ,将其命名为 cluster.conf ,并将每行配置成ip:port。(请配置3个或3个以上节点)
# ip:port
127.0.0.1:8848
127.0.0.1:8849
127.0.0.1:8850
由于是单机演示,需要更改nacos/的conf目录下application.properties中server.port,防止端口冲突。如果服务器有多个ip也要指定具体的ip地址,如:nacos.inetutils.ip-address=127.0.0.1
例如:
server.port=8850
nacos.inetutils.ip‐address=127.0.0.1
(3)集群模式启动
分别执行nacos目录的bin目录下的startup:
startup ‐m cluster
在任意一个nacos的控制台中,可以看到如下内容:
5.3.2 客户端配置
所有客户端,分别指定nacos集群中的若干节点:
测试,使用快速上手的例子:
(1)关掉127.0.0.1:8848 nacos Leader实例,发现Leader被成功选举至127.0.0.1:8850
(2)紧接着重新启动Provider,这时马上请求consumer的/service出现错误,发现consumer与provider通信已经出现问题。但经过短暂的时间后,通信恢复。
通过测试,我们可以看到,通过以上的集群部署已经达到了高可用的效果。
5.3.3 生产环境部署建议
下图是官方推荐的集群方案,通过域名 + VIP模式的方式来实现。客户端配置的nacos,当Nacos集群迁移时,客户端配置无需修改。
至于数据库,生产环境下建议至少主备模式。通过修改${nacoshome}/conf/application.properties文件,能够使nacos拥有多个数据源。