3 Nacos配置管理
3.1 理解配置中心
3.1.1 什么是配置
应用程序在启动和运行的时候往往需要读取一些配置信息,配置基本上伴随着应用程序的整个生命周期,比如:数 据库连接参数、启动参数等。
配置主要有以下几个特点:
配置是独立于程序的只读变量
配置对于程序是只读的,程序通过读取配置来改变自己的行为,但是程序不应该去改变配置 配置伴随应用的整个生命周期
配置贯穿于应用的整个生命周期,应用在启动时通过读取配置来初始化,在运行时根据配置调整行为。 比如:启动时需要读取服务的端口号、系统在运行过程中需要读取定时策略执行定时任务等。
配置可以有多种加载方式
常见的有程序内部hard code,配置文件,环境变量,启动参数,基于数据库等,配置需要治理
同一份程序在不同的环境(开发,测试,生产)、不同的集群(如不同的数据中心)经常需要有不同的 配置,所以需要有完善的环境、集群配置管理
3.1.2 什么是配置中心
在微服务架构中,当系统从一个单体应用,被拆分成分布式系统上一个个服务节点后,配置文件也必须跟着迁移
(分割),这样配置就分散了,不仅如此,分散中还包含着冗余,如下图:
下图显示了配置中心的功能,配置中心将配置从各应用中剥离出来,对配置进行统一管理,应用自身不需要自己去 管理配置。
配置中心的服务流程如下:
1、用户在配置中心更新配置信息。
2、服务A和服务B及时得到配置更新通知,从配置中心获取配置。
总得来说,配置中心就是一种统一管理各种应用配置的基础服务组件。
在系统架构中,配置中心是整个微服务基础架构体系中的一个组件,如下图,它的功能看上去并不起眼,无非就是 配置的管理和存取,但它是整个微服务架构中不可或缺的一环。
总结一下,在传统巨型单体应用纷纷转向细粒度微服务架构的历史进程中,配置中心是微服务化不可缺少的一个系 统组件,在这种背景下中心化的配置服务即配置中心应运而生,一个合格的配置中心需要满足如下特性:
配置项容易读取和修改
分布式环境下应用配置的可管理性,即提供远程管理配置的能力 支持对配置的修改的检视以把控风险
可以查看配置修改的历史记录
不同部署环境下应用配置的隔离性
3.1.3 主流配置中心对比
目前市面上用的比较多的配置中心有:Spring Cloud Config、Apollo、Nacos和Disconf等。由于Disconf不再维护,下面主要对比一下Spring Cloud Config、Apollo和Nacos。
对比项目 | Spring Cloud Config | Apollo | Nacos |
配置实时推送 | 支持(Spring Cloud Bus) | 支持(HTTP长轮询1s内) | 支持(HTTP长轮询1s内) |
版本管理 | 支持(Git) | 支持 | 支持 |
配置回滚 | 支持(Git) | 支持 | 支持 |
灰度发布 | 支持 | 支持 | 不支持 |
权限管理 | 支持(依赖Git) | 支持 | 不支持 |
多集群 | 支持 | 支持 | 支持 |
多环境 | 支持 | 支持 | 支持 |
监听查询 | 支持 | 支持 | 支持 |
多语言 | 只支持Java | 主流语言,提供了Open API | 主流语言,提供了Open API |
配置格式校验 | 不支持 | 支持 | 支持 |
单机读(QPS) | 7(限流所致) | 9000 | 15000 |
单击写(QPS) | 5(限流所致) | 1100 | 1800 |
3节点读(QPS) | 21(限流所致) | 27000 | 45000 |
3节点写(QPS) | 5(限流所致) | 3300 | 5600 |
从配置中心角度来看,性能方面Nacos的读写性能最高,Apollo次之,Spring Cloud Config依赖Git场景不适合开放的大规模自动化运维API。功能方面Apollo最为完善,nacos具有Apollo大部分配置管理功能,而Spring Cloud
Config不带运维管理界面,需要自行开发。Nacos的一大优势是整合了注册中心、配置中心功能,部署和操作相比
Apollo都要直观简单,因此它简化了架构复杂度,并减轻运维及部署工作。
综合来看,Nacos的特点和优势还是比较明显的,下面我们一起进入Nacos的世界。
3.2 Nacos配置管理
3.2.1 发布配置
首先在nacos发布配置,nacos-restful-consumer服务从nacos读取配置。
浏览器访问 http://127.0.0.1:8848/nacos ,打开nacos控制台,并点击菜单配置管理**->配置列表**: 在Nacos添加如下的配置:
nacos-restful-consumer:
Namespace: public
DataID: nacos-restful-consumer.yaml
Group: DEFAULT_GROUP
配置格式: YAML
配置内容:
common:
name: application1 config
3.2.2 获取配置
要想从配置中心获取配置 添加nacos-config的依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
在bootstrap.yml添加配置:
spring:
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848 # 配置中心地址
file-extension: yaml
group: DEFAULT_GROUP
注意:要使用配置中心就要在bootstrap.yml中来配置,bootstrap.yml配置文件的加载顺序要比application.yml要优先。
在nacos-restful-consumer工程的controller中增加获取配置的web访问端点/configs,
通过标准的spring @Value方式。
@Value("${common.name}")
private String common_name;
@GetMapping(value = "/configs")
public String getvalue(){
return common_name;
}
基于上面的例子,若要实现配置的动态更新,只需要进行如下改造:
// 注入配置文件上下文
@Autowired
private ConfigurableApplicationContext applicationContext;
@GetMapping(value = "/configs")
public String getConfigs(){
return applicationContext.
getEnvironment().getProperty("common.name");
}
我们通过nacos控制台更新common.name的配置值,再次访问web端点/configs,发现应用程序能够获取到最新的配置值,
说明spring-cloud-starter-alibaba-nacos-config 支持配置的动态更新。
Note:可以通过配置
spring.cloud.nacos.config.refresh.enabled=false
来关闭动态刷新
3.2.3 配置管理模型
对于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
在config中指定namespace,例子如下:
config:
server-addr: 127.0.0.1:8848 # 配置中心地址
file-extension: yaml
namespace: 4883fa0a-8f2b-4b3d-b8f5-261dfe06a323 # 开发环境
group: DEFAULT_GROUP # xx业务组
3、group,如不指定默认 DEFAULT_GROUP
见上边第2点的例子。
4、dataId,必须指定,名称为应用名称+配置文件扩展名
3.3 自定义扩展的 Data Id 配置
3.3.1 ext-config扩展配置
Spring Cloud Alibaba Nacos Config可支持自定义 Data Id 的配置。 一个完整的配置案例如下所示:
server:
port: 56020
nacos:
server:
addr: 127.0.0.1:8848
provider:
address: 127.0.0.1:56010
spring:
application:
name: nacos_consumer
cloud:
nacos:
discovery:
server-addr: ${nacos.server.addr}
config:
server-addr: ${nacos.server.addr} # 配置中心地址
file-extension: yaml
ext-config[0]:
data-id: ext-common.yaml
group: COMMON_GROUP
refresh: true
可以看到:
通过 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 在配置变更时,是否支持应用中可动态刷新, 感知到最新的配置值。默认是不支持的。
spring.cloud.nacos.config.ext -config[n].data-id 的值必须带文件扩展名,文件扩展名既可支持 properties,又可以支持 yaml/yml。 此时 spring.cloud.nacos.config.file -extension 的配置对自定义扩 展配置的 Data Id 文件扩展名没有影响。
测试:
配置ext-config-common01.yaml:
配置ext-config-common02.yaml:
编写测试代码:
@GetMapping(value = "/configs")
public String getvalue(){
String name = applicationContext.
getEnvironment().getProperty("common.name");
String address = applicationContext.
getEnvironment().getProperty("common.addr");
return name + address;
}
重启nacos-restful-consumer工程
访问 :http://127.0.0.1:56020/configs 通过测试发现:
扩展配置优先级是 spring.cloud.nacos.config.ext -config[n].data-id 其中 n 的值越大,优先级越高。 通过内部相关规则(应用名、扩展名 )自动生成相关的 Data Id 配置的优先级最大。
3.3.2 案例
案例需求如下:
1、抽取servlet公用的配置到独立的配置文件,配置文件内容如下:
#tomcat头信息和访问路径配置
server:
tomcat:
remote_ip_header: x‐forwarded‐for
protocol_header: x‐forwarded‐proto
servlet:
context‐path: /a
use‐forward‐headers: true
2、如果有context-path的个性配置可以单独设置实现如下:
1、抽取servlet公用的配置到独立的配置文件
在nacos-restful-consumer中添加扩展配置文件,下图中红色框内为指定的配置文件名称:
在nacos中添加扩展配置文件,下图中红色框内是servlet公用的配置内容。
发布配置,重启nacos-restful-consumer
访问 http://127.0.0.1:56020/a/configs 验证配置是否生效
2、如果有context-path的个性配置可以单独设置
这里我们需要对nacos-restful-consumer的context-path设置为根路径,如何实现?
方案1:修改ext-config-http.yaml中context-path为根路径,但是此文件定义为公用配置文件,其它服务也使用了,此方案不可行。
方案2:在nacos-restful-consumer.yaml中定义context-path为根路径,因为nacos-restful-consumer.yaml单独属于nacos-restful-consumer工程,且nacos-restful-consumer.yaml的优先级比ext-config-http.yaml高,所以此方案可行。
在nacos中配置nacos-restful-consumer.yaml,如下:
重启nacos-restful-consumer工程。
测试,请求:http://127.0.0.1:56020/configs