1.什么是Nacos
以下部分解释摘自于Nacos官方文档:
Nacos 致力于帮助您发现、配置和管理微服务。Nacos提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
其实Nacos就是第一代微服务中的注册中心Eureka和Spring Cloud Config配置中心的合体,由国内知名的Bat公司Alibaba团队开源,在第二代微服务Spring Cloud Alibaba中被广泛使用,你完全可以使用nacos替换eureka和config这两个组件。
Nacos可以实现分布式服务注册与发现和分布式配置中心动态管理
Nacos 文档: https://nacos.io/zh-cn/docs/what-is-nacos.html
Spring Cloud Alibaba文档: Spring Cloud Alibaba Reference Documentation
2.依赖管理
3.nacos-client搭建
3.1.新建SpringBoot项目
springcloud-alibaba-nacos
com.bruce.springcloud-alibaba-nacos
1.0-SNAPSHOT
4.0.0
springcloud-alibaba-nacos-client
org.springframework.boot
spring-boot-starter-web
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
2.1.1.RELEASE
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
2.1.1.RELEASE
org.projectlombok
lombok
1.18.12
provided
3.2.配置连接nacos-server
注意: Spring Boot 配置文件的加载顺序:依次为 bootstrap.properties -> bootstrap.yml -> application.properties -> application.yml ,其中 bootstrap.properties 配置为最高优先级
nacos官方文档要求,指定配置文件必须放在bootstrap.properties或者bootstrap.yml中加载初始化,因为在整个SpringBoot应用程序中bootstrap.properties/yml类型的文件优先级最高加载,所以我们把配置文件都放入到bootstrap.yml中。
application.yml
因为项目的端口上了生产环境之后不会轻易更该,因此不需要动态管理配置
server:
port: 8010
bootstrap.yml
项目启动时加载和查找配置中心文件的过程原理:
项目启动的时候,默认会去加载查找Data ID为nacos-config.yaml的配置文件;如果你设置了多环境配置profiles.active,这个时候不仅会默认加载nacos-config.yaml,另外还会去加载查找nacos-config-dev.yaml这个名称的文件。多环境下会加载查找两个文件,不指定多环境下会只默认加载一个。
你可以通过配置 spring.cloud.nacos.config.refresh.enabled=false 来关闭动态刷新
可支持profile粒度的配置
spring-cloud-starter-alibaba-nacos-config 在加载配置的时候,不仅仅加载了以 dataid 为 ${spring.application.name}.${file-extension:properties} 为前缀的基础配置,还加载了dataid为 ${spring.application.name}-${profile}.${file-extension:properties} 的基础配置。在日常开发中如果遇到多套环境下的不同配置,可以通过Spring 提供的 ${spring.profiles.active} 这个配置项来配置。
spring.profiles.active=dev
${spring.profiles.active} 当通过配置文件来指定时必须放在 bootstrap.properties 文件中。
Nacos 上新增一个dataid为:nacos-config-dev.yaml的基础配置,如下所示:
Data ID: nacos-config-dev.yaml
Group : DEFAULT_GROUP
配置格式: YAML
配置内容: current.env: develop-env
项目加载过程截图如下:
spring:
application:
#对应Nacos Config中的Data ID,不是指服务名,实际服务应用名称以配置中心文件为准
name: nacos-config
cloud:
nacos:
discovery:
#Nacos注册中心地址
server-addr: 127.0.0.1:8848 #,127.0.0.1:8849,127.0.0.1:8850
enabled: true
config:
#Nacos配置中心地址
server-addr: 127.0.0.1:8848 #,127.0.0.1:8849,127.0.0.1:8850
#分组选择
group: DEFAULT_GROUP
#类型(默认加载.properties),默认指定查找nacos-config.yaml
file-extension: yaml
#读取环境配置,指定环境后,还会加载nacos-config-dev.yaml文件
profiles:
active: dev
启动项目成功后,会注册到nacos上:
4.读取nacos-server上数据
4.1.动态刷新方式一:
@RefreshScope : 在所要使用配置文件参数值的类上加这个注解会自动实现动态刷新,只要nacos-server端一有文件发生变化,会动态刷新配置。
NacosController
package com.bruce.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @BelongsProject: springcloud-alibaba-nacos
* @BelongsPackage: com.bruce.controller
* @CreateTime: 2021-02-19 10:45
* @Description: TODO
*/
@Slf4j
@RestController
@RefreshScope
public class NacosController {
@Value("${user.name}")
private String userName;
@GetMapping("/getConfig")
public String getConfig() {
log.info("从nacos-server读取的数据=>>>>>: {}", userName);
return userName;
}
}
4.2.动态刷新方式二:
@Slf4j
@RestController
public class HelloController {
@Autowired
private ConfigurableApplicationContext applicationContext;
@GetMapping("/getConfig1")
public String getServerPort(){
String name = applicationContext.getEnvironment().getProperty("user.name");
log.info("内容是===>>>: , {}", name);
return name;
}
}
5.启动类
package com.bruce;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.SpringCloudApplication;
/**
* @BelongsProject: springcloud-alibaba-nacos
* @BelongsPackage: com.bruce
* @CreateTime: 2021-02-18 13:16
* @Description: TODO
*/
@SpringBootApplication
public class AppNacosClient {
public static void main(String[] args) {
SpringApplication.run(AppNacosClient.class);
}
}
6.测试
nacos-server新建nacos-config-dev.yaml文件
访问 http://127.0.0.1:8010/getConfig展示如下结果:
修改user.name的值,不重启项目,再次访问:
实现动态刷新
7.Nacos配置中心原理总结
7.1.Md5何时变更
在长轮询的任务中,当服务端配置信息发生变更时,客户端将最新的数据获取下来之后,保存在了 CacheData 中,同时更新了该 CacheData 的md5值,所以当下次执行 checkListenerMd5 方法时,对前后两次的MD5值作比对,就会发现当前listener所持有的 md5 值已经和 CacheData 的 md5 值不一样了,也就意味着服务端的配置信息发生改变了,这时就需要将最新的数据通知给 Listener 的持有者。
至此配置中心的完整流程已经分析完毕了,可以发现,Nacos 并不是通过推的方式将服务端最新的配置信息发送给客户端的,而是客户端维护了一个长轮询的任务,定时去拉取发生变更的配置信息,然后将最新的数据推送给 Listener 的持有者。
7.2.总结
在Nacos服务端创建了相关的配置项后,客户端就可以进行监听了。
客户端是通过一个长轮询的定时任务来检查自己监听的配置项的数据的,一旦服务端的数据发生变化时,客户端将会获取到最新的数据,并将最新的数据保存在一个 CacheData 对象中,然后会重新计算 CacheData 的 md5 属性的值,此时就会对该 CacheData 所绑定的 Listener 触发 receiveConfigInfo 回调。
考虑到服务端故障的问题,客户端将最新数据获取后会保存在本地的 snapshot 文件中,以后会优先从文件中获取配置信息的值,当前环境下快照地址为:C:\Users\bruceliu\nacos\config\fixed-127.0.0.1_8848_nacos\snapshot\DEFAULT_GROUP。