一、使用场景
当应用的服务部署实例越来越多,达到数十、数百个时,要修改服务的配置的时候,如果要一个一个实例去修改,这是一件很令人崩溃的事,而且很容易出错。此时我们需要一种统一的配置管理方案,可以集中管理所有实例的配置信息。nacos一方面可以将配置集中管理,另一方面,在配置变更时,nacos可以及时通知微服务,实现配置的热更新
二、使用方法
1、在nacos中添加配置
注意:项目的核心配置,需要热更新的配置才有放到nacos管理的必要。基本不会变更的一些配置还是保存在微服务本地比较好
2、在代码中拉取配置中的信息
微服务要拉取nacos中管理的配置信息,并且与本地的application.yml配置文件合并,才能完成项目的启动
问题来了,我们没有读取到application.yml中的信息,而nacos地址信息又在application.yml文件中,那我们怎么去拉取nacos中的配置信息呢?
因此,spring引入了一种新的配置文件:bootstrap.yaml文件,这个文件会在读取application.yml文件之前读取,流程如下:
3、配置拉取步骤
①在pom中引入nacos配置管理的依赖
<!--nacos配置管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
②添加bootstrap.yml配置文件(需要配置的内容有服务名称、环境、nacos地址、文件的后缀名)如下:
spring:
application:
name: userservice # 服务名称
profiles:
active: dev #开发环境,这里是dev
cloud:
nacos:
server-addr: localhost:8848 # Nacos地址
config:
file-extension: yaml # 文件后缀名
根据bootstrap.yml配置文件根据spring.cloud.nacos.server-adddr 可以找到nacos,并根据${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension},也就是配置的文件id,来获取配置文件。
③读取配置文件中的内容
Ⅰ、使用@Value()注解,可以获得配置文件的属性
@Value("${user.age}") private Integer age;
注:该注解的作用是将我们配置文件的属性读出来,有@Value(“${}”)和@Value(“#{}”)两种方式:简单来说:
@Value("${}") 是读取的配置文件的属性,例如: @Value("${server.port}")
@Value("#{}") 是读取组件(类)中的属性,例如: @Value(""#{UserBean.name})
④配置的热更新(两种方法)
Ⅰ、在使用了@Value()注解的类上添加@RefreshScope注解即可完成配置热更新
Ⅱ、使用@ConfigurationProperties注解代替@Value()注解,并在服务中添加一个类,读取配置文件中的属性,具体如下:
@Component @Data @ConfigurationProperties(prefix = "pattern")//这是配置项的前缀 public class PatternProperties { private String dateformat; //这是配置项的值(两者组合起来就是配置文件中的配置项) }
而后在需要使用到的地方注入这个类,通过调用属性的get、set方法获得配置项的值
三、配置共享
其实在微服务启动的时候,会去nacos读取多个配置文件,例如:
[ spring.application.name]-[spring.profiles.active].yaml , 例如userservice-dev.yaml userservice-test.yaml
[ spring.application.name].yaml 例如: userservice.yaml
因为[ spring.application.name].yaml 这种配置文件不包含环境的内容,因此它可以被多个环境共享。
测试:①在nacos中添加两个配置文件分别为 userservice-dev.yaml 和 userservice.yaml
②在服务的bootstrap.yaml文件中配置环境为dev环境,启动去获得这两个配置文件的内容都是可以获得的;
但是在bootstrap.yaml文件中配置环境为test之后,再次启动去获得这两个配置文件的内容时发现,带dev的配置文件的配置项获取不到了,而不带环境的配置文件中的配置项依然可以获得
目前我们知道有三种配置文件了application.yml(本地配置) 、服务名-环境.yaml 、服务名.yaml
那如果这三个配置文件都存在,且其中都有一段相同的配置项,那么最终会以谁的为准呢?通过测试发现,他们之间的优先级关系是:
application.yml(本地配置) < 服务名.yaml < 服务名-环境.yaml
四、nacos集群搭建
1、为了服务的高可用,增强架构的容灾性,通常都会将nacos集群部署。集群的结构图如下:
其中包含3个nacos节点,然后一个负载均衡器代理3个Nacos。这里负载均衡器可以使用nginx
nacos三个节点的地址规划:(实际中应该会是三台不同的机器,这里是在本地部署)
节点 | ip | port |
---|---|---|
nacos1 | 192.168.150.1 | 8845 |
nacos2 | 192.168.150.1 | 8846 |
nacos3 | 192.168.150.1 |
2、搭建集群步骤:
①搭建数据库,初始化数据库的表结构(nacos的安装包中有提供)
②下载nacos安装包
③配置nacos
Ⅰ、将cluster.conf.example配置文件更名使其生效
Ⅱ、进入cluster.conf中将所有节点ip和端口信息添加上去
例如:
127.0.0.1:8845
127.0.0.1.8846
127.0.0.1.8847
Ⅲ、修改application.properties配置文件,将数据库相关配置修改并且放开注解
Ⅳ、此处因为是本地模拟集群,所以还要到application.properties中修改端口号
④bin目录下使用startup.cmd启动nacos
③nginx反向代理配置
Ⅰ、获得nginx的安装包并解压到非中文目录下
Ⅱ、修改conf/nginx.conf配置文件,配置如下:
upstream nacos-cluster {
server 127.0.0.1:8845;
server 127.0.0.1:8846;
server 127.0.0.1:8847;
}
server {
listen 80;
server_name localhost;
location /nacos {
proxy_pass http://nacos-cluster;
}
}
④而后在浏览器访问 http://localhost/nacos 即可进入nacos面板
⑤记得在服务的appliation.yml中修改nacos的地址的配置为是 server-addr: 127.0.0.1:80
优化之处: