使用Nacos实现配置管理
# 使用Nacos实现配置管理
# 为什么要配置管理
那在微服务架构当中,我们的配置文件肯定会非常的多。因为服务多,服务动不动就是几十个,甚至成百上千个都有可能。并且每一个服务,我们还需要为不同的环境去创建不同的配置文件。这样一来的话,配置文件就更多了,对吧?这配置文件当中肯定会存在一些相同特征的一些类似的配置信息。这些相同的配置信息,我们肯定也需要在每一份配置文件都给它去维护一份。
这无疑会为我们增加运维负担,同时这么多的数据也容易出错。
这些相同的配置信息一旦涉及到改的话,是不是涉及到的这些配置文件都要去改?比方说这个redis,比方说点10这1台redis的服务不被好几台微服务进行了连接。假如说点10这1台redis,有一天发生了服务的变更,比如要改成12,那么这些相关的这这些微服务我是不是都要去改?我是不是得找到相关的那些微服务,找到它里面的这些配置文件,然后进行更改。改完之后,我还得重启,对不对?
再比如,在电商系统里面,经常会需要搞大促,对不对?一搞大促的话,这些像redis,数据mq等等,都要去给它加机器。一加机器,有可能他们的这个地址就会发生变化,对不对?一发生变化,我们就得进行更改,改完了又得重启。等大促过完之后,可能又又得变回来,我们又要去更改。所以说在我们这种微服务架构当中,以前这种传统的配置文件已经没有办法满足了,对不对?
以上描述的这种工作不难,只是量很大,且每一份都是重复的。怎么解决呢?有解法的,机器去完成,换句话说用程序来实现这部分任务。因为程序就是用来提高效率,解决重复的工作的工具。
此外,除了运维负担大,还有另外2个问题,需要注意。
- 它的时效性。我们改完这个配置文件,你必须要进行重启。尤其是在我们刚才说的电商这种大促的情况下,我要经常的对这种配置文件进行变更。变更的话我又得频繁的重启,重启之后才能生效,对不对?在没有重启之内,它是没有办法达到每一个服务都是一致性的,对不对?
- 安全性,比方说我们以前不管是哪个环境,我们都会在配置文件当中去维护这些远程地址的IP、端口、用户名、密码都会暴露在配置文件当中。对不对?一旦遇到了这种居心叵测的程序员,当然也不能有时候也不能全怪程序员,对不对?有时候碰到一些恶心的公司对不对?比如说不发工资...
# 前置条件
nacos需要先成功启动,前文已经说明方法,这里不再介绍,Nacos官网 (opens new window)
# 配置管理的优势
在分布式系统中,配置管理显得尤为重要。实现配置管理可以使系统更加便于监控,因为所有的配置信息都可以通过接口获取,可以很方便的查看配置信息是否改变,从而及时调整系统运行状态。
使用Nacos实现配置管理的优势主要有以下几点:
- 减少配置:将配置集中管理,避免了在各个服务中维护配置的问题。这样可以减少配置的错误和冗余,提高系统的稳定性。
- 动态更新:Nacos支持动态更新配置,可以快速地将配置的变化传递给各个服务。
- 高可用性和可扩展性:Nacos具有高可用性和可扩展性,可以支持大量的服务和配置。这样可以提高系统的可用性和性能。
- 灵活性:Nacos支持多种类型的配置,可以满足不同的业务需求。例如,Nacos支持配置文件、数据库、Redis等多种存储方式。
- 实现了权限管理,能对访问人员进行权限控制
同为配置管理中心的组件还有,cloud config以及apollo。它们的区别这里就不展开了,欢迎自行查阅。
# 实现配置管理
# 在Nacos中进行配置
进入Nacos控制页面,在配置列表
页面——进行新建配置,用于后续的调用
Data ID
:填入alibaba-nacos-config-demo.properties
Group
:不修改,使用默认值DEFAULT_GROUP
配置格式
:选择Properties
配置内容
:应用要加载的配置内容(开发中的配置信息就写到此处)。这里我随意写一点demo.title=demo-config-learning
其中Data ID
的写法,nacos官网有个标准--应为如下格式:
${prefix}-${spring.profiles.active}.${file-extension}
prefix
默认为spring.application.name
的值,也可以通过配置项spring.cloud.nacos.config.prefix
来配置。spring.profiles.active
即为当前环境对应的 profile,详情可以参考 Spring Boot文档 (opens new window)。 注意:当spring.profiles.active
为空时,对应的连接符-
也将不存在,dataId 的拼接格式变成${prefix}.${file-extension}
file-exetension
为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension
来配置。目前只支持properties
和yaml
类型。
# 引入依赖
其中spring-cloud-starter-alibaba-nacos-config
是实现配置管理的包
<properties>
<java.version>1.8</java.version>
<spring.cloud.version>2021.0.1</spring.cloud.version>
<spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- nacos 启用配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 配置bootstrap.properties
在 bootstrap.properties
中配置 Nacos server 的地址和应用名
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.application.name=alibaba-nacos-config-demo
2
3
其中spring.application.name
值必须与之前Nacos中配置的Data Id匹配。
bootstrap.properties
和application.properties
是Spring Boot中的两种不同的配置文件,它们在使用场景和加载顺序上有一些区别
- application.properties是应用程序的主要配置文件,用于配置应用程序的各种属性和行为,包含了应用程序特定的配置信息,如数据库连接、日志级别、Web服务器端口等;
- bootstrap.properties是用于配置Spring Boot的基础设施和全局属性的配置文件,主要用于加载外部配置和配置基础设施,如服务发现、分布式配置中心、安全认证等。
bootstrap.properties
在Spring Boot应用程序启动时优先于最先application.properties
加载,但若两者中出现同样的配置,则application.properties
的配置会优先覆盖bootstrap.properties的配置
Spring Boot 2.4版本开始,对配置文件加载方式进行了重构,只会识别application.* 配置文件,并不会自动识别bootstrap.yml;
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
2
3
4
如果直接写入bootstrap.yml(或bootstrap.properties)则不生效,需要引入(以上的)依赖。
bootstrap.yml,它是spring cloud扩展出来的一个配置文件。加载顺序在Application之前。
# 项目实现
定义Controller,其中通过@Value
注解,注入了来自配置中心——key为demo.title
的配置。
@RestController
@RefreshScope
public class TestController {
@Value("${demo.title}")
private String title;
@GetMapping("/test")
public String hello() {
return title;
}
}
2
3
4
5
6
7
8
9
10
11
12
加上注解@RefreshScope
,可以使该类下的配置内容支持动态刷新,也就是当我们的应用启动之后,修改了Nacos中的配置内容之后,这里也会马上生效。
最后,启动项目,如果在输出日志中看到如下内容,即为读取配置成功
2023-10-11 20:22:46.414 INFO 24305 --- [ main] c.a.c.n.refresh.NacosContextRefresher : listening config: dataId=alibaba-nacos-config-client, group=DEFAULT_GROUP
2023-10-11 20:22:46.414 INFO 24305 --- [ main] c.a.c.n.refresh.NacosContextRefresher : listening config: dataId=alibaba-nacos-config-client.properties, group=DEFAULT_GROUP
2
访问: http://127.0.0.1:8080/test
,即可看到返回内容为之前定义的:spring-cloud-alibaba-learning--practice makes perfect
或者你可以通过一下方式获取。
@SpringBootApplication
@Slf4j
public class OrderApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(OrderApplication.class, args);
String username = applicationContext.getEnvironment().getProperty("demo.title");
}
}
2
3
4
5
6
7
8
9
10
11
12
# 注意
# 权限控制
如果要启动权限控制功能,需要修改配置文件。
conf文件夹下,application.properties当中这个配置项给它设置为true。否则即使设置了权限,也不会生效。
### If turn on auth system:
nacos.core.auth.enabled=false
2
3
默认值为 false。
# @RefreshScope
@RefreshScope
的优势在于它实现了配置文件的动态加载,也就是说,当在配置服务器上更新了配置信息后,RefreshScope会自动将最新的配置信息注入到应用中,从而不需要重启应用就能加载新的配置信息。
但在一些情况下,它会失效:
- 如当它修饰在@Scheduled、listener、Timmer等类中时
- 当配置刷新导致的对象被清除而又没法重新使用对象时,RefreshScope可能无法生效
此外,@RefreshScope
只适用于SpringCloud环境,对于其他环境则需要使用其他方式实现动态加载配置。
# 参数Data ID等说明
上述的例子中,我们在Nacos中进行的配置使用的是默认配置,根据官网的说明——我们可以自定义:
- Data ID
之前的Data ID
:对应的是spring.application.name=${name}
# 如果我们定义了以下属性 则 Data ID应为demo
spring.cloud.nacos.config.prefix=demo
2
- Group 它的默认值为:DEFAULT_GROUP
# 我们可以用它来区分不同用途的配置内容
spring.cloud.nacos.config.group=DEV_GROUP
2
- 配置内容的格式 进行如下配置后,Nacos中配置内容的数据格式则为
yaml
spring.cloud.nacos.config.file-extension=yaml
- 不同环境的使用
spring.profiles.active=test
若指定了环境,则Group ID则变为:${prefix}-test.${file-extension}
以上4个属性可以配合使用实现不同环境的配置,此外还可以使用Namespace
实现不同环境的配置这一功能。
在命名空间新建一个namespace,再在其中创建对应的Group
跟Data ID
即可。
使用Namespace后,不同的命名空间下,可以存在相同的Group
或Data ID
的配置。