1、理解Nacos
1.1 什么是配置
应用程序在启动和运行的时候往往需要读取一些配置信息,配置基本上伴随着应用程序的整个生命周期,比如:数 据库连接参数、启动参数等。
配置主要有以下几个特点:
1
)配置是独立于程序的只读变量
配置对于程序是只读的,程序通过读取配置来改变自己的行为,但是程序不应该去改变配置
2
)配置伴随应用的整个生命周期
配置贯穿于应用的整个生命周期,应用在启动时通过读取配置来初始化,在运行时根据配置调整行为。比如:启动时需要读取服务的端口号、系统在运行过程中需要读取定时策略执行定时任务等。
·配置可以有多种加载方式
常见的有程序内部
hard code
,配置文件,环境变量,启动参数,基于数据库等
·配置需要治理
同一份程序在不同的环境(开发,测试,生产)、不同的集群(如不同的数据中心)经常需要有不同的配置,所以需要有完善的环境、集群配置管理
1.2 什么是配置中心
在微服务架构中,当系统从一个单体应用,被拆分成分布式系统上一个个服务节点后,配置文件也必须跟着迁移 (分割),这样配置就分散了,不仅如此,分散中还包含着冗余。如下图
配置中心的服务流程如下:
1
、用户在配置中心更新配置信息。
2
、服务
A
和服务
B
及时得到配置更新通知,从配置中心获取配置。 总得来说,配置中心就是一种统一管理各种应用配置的基础服务组件。
1.3 Nacos简介
1.3.1 主流配置中心对比
目前市面上用的比较多的配置中心有:
Spring Cloud Config
、
Apollo(
携程开源项目
)
、
Nacos(
阿里巴巴开源项目)
等。
![](https://i-blog.csdnimg.cn/blog_migrate/285ce36212c863f691adbb13777ac13b.png)
从配置中心角度来看,性能方面
Nacos
的读写性能最高,
Apollo
次之,
Spring Cloud Config
依赖
Git
场景不适合开放的大规模自动化运维API
。功能方面
Apollo
最为完善,
nacos
具有
Apollo
大部分配置管理功能,而Spring Cloud Config
不带运维管理界面,需要自行开发。
Nacos
的一大优势是整合了注册中心、配置中心功能,部署和操作相比 Apollo
都要直观简单,因此它简化了架构复杂度,并减轻运维及部署工作。 综合来看,Nacos
的特点和优势还是比较明显的。
1.3.2 什么是Nacos
来自于官网
https://nacos.io/zh-cn/docs/what-is-nacos.html
Nacos
致力于帮助您发现、配置和管理微服务。
Nacos
提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。
Nacos
是构建以
“
服务
”
为中心的现代应用
架构
(
例如微服务范式、云原生范式
)
的服务基础设施。
1.3.3 Nacos关键特性
服务发现和服务健康监测
动态配置服务
动态
DNS
服务
服务及其元数据管理
2、安装Nacos
2.1 预备环境准备
Nacos
依赖
Java
环境来运行。如果您是从代码开始构建并运行
Nacos
,还需要为此配置
Maven
环境,
请确保是在以下版本环境中安装使用
:
64 bit OS
,支持
Linux/Unix/Mac/Windows
,推荐选用
Linux/Unix/Mac
。
64 bit JDK 1.8+
;下载
&
配置。
Maven 3.2.x+
;下载
&
配置。
2.2 下载安装包
下载地址:
https://github.com/alibaba/nacos/releases
windows
nacos-server-2.0.3.zip (讲解以
windows
为主
)
Linux
nacos-server-2.0.3.tar.gz
2.3 安装
将压缩包
nacos-server-2.0.3.zip
解压至目录,
注意:
nacos
安装目录不能带有中文
,
否则启动时可能会
有问题
2.4 启动服务
nacos
的默认端口是
8848
,需要保证
8848
默认端口没有被其他进程占用,查看
conf
目录下的
application.properties
文件内容
#*************** Spring Boot Related Configurations ***************#
### Default web context path:
server.servlet.contextPath=/nacos
### Default web server port:
server.port=8848
nacos
默认是以集群模式启动,单机模式启动打开
CMD
窗口 使用命令
startup.cmd -m standalone
运 行,或者修改 startup.cmd
文件,将
MODE=”cluster“
修改为
MODE="standalone"
执行
startup.cmd
以单机模式启动,端口
Port
为
8848
![](https://i-blog.csdnimg.cn/blog_migrate/f369702d7430778c877ef1c81a5bf3c0.png)
2.5 打开控制界面
启动成功,可通过浏览器访问
http://127.0.0.1:8848/nacos
,打开如下
nacos
控制台登录页面:
默认用户名:
nacos
默认密码:
nacos
![](https://i-blog.csdnimg.cn/blog_migrate/ab97fc54520d0b305a8b8a4e76665466.png)
2.6 关闭服务
双击
bin
目录下的
shutdown.cmd
关闭服务
Alibaba Nacos
提供
了
OPEN API
帮助文档,地址
https://nacos.io/zh-cn/docs/open-api.html
,其他
API
可以查看帮助 文档。
3、Nacos分布式应用配置中心
3.1 nacos发布微服务配置
3.1.1 为什么需要配置管理
在微服务架构中,每个
微服务
都有可能会
存在多个实例
,为了
保证同一微服务不同实例
的
配置文件
内容一致
,我们就需要有一个服务可以对微服务项目的配置文件进行统一管理,通常我们将其称之为统
一配置管理中心。因为如果配置文件的内容不一致,有可能会导致同一微服务的不同实例在行为上发生
差异,从而导致一些错误。
除此之外,在企业开发中还要求项目在不同环境使用不同配置,以及可以在不重启服务的情况下实
现配置文件的动态刷新,为了实现这些需求我们也得使用到统一配置管理中心。
3.1.2 服务配置流程
· 用户通过
nacos
服务的控制台对配置文件进行集中管理
· 各服务统一从
nacos
中获取各自的配置
,
并监听配置的变化
3.1.3 Nacos发布配置
浏览器访问
http://127.0.0.1:8848/nacos
,打开
nacos
控制台,分别进行如下操作
1.创建开发环境命名空间
2.在
DEV
命名空间下创建
service1
服务配置
3.2 搭建工程从nacos获取配置
3.2.1 创建父工程修改pom配置
1
)添加
packaging
标签设置为
pom
,用于管理子模块和依赖关系
<packaging>pom</packaging>
2
)添加如下配置
<!-- 这里的属性会被子模块继承 -->
<properties>
<project.build.sourceEncoding>UTF‐8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF‐8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-boot.version>2.2.5.RELEASE</spring-boot.version>
<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<!-- 子模块继承父模块之后,提供作用:锁定版本 + 子模块不用再写 version -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.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>
<!-- Spring Cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!--Maven插件,用于打包-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3.2.2 创建子模块service1
1
)添加
pom
依赖
<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
)在
resources
下创建
bootstrap.yml
配置文件并添加配置
server:
port: 8081
spring:
application:
name: service1
cloud:
nacos:
config:
server-addr: localhost:8848 #nacos配置中心服务地址
file-extension: yml #文件扩展名
namespace: 1cbb6273-c03a-43e4-ac3a-9d67578ffb73 #命名空间,注意:使用自己的命名空间
group: TEST_GROUP #分组名
# 查找默认的data Id --> 应用名 + 文件扩展名-->service1.yaml
备注:
为什么要使用
bootstrap.yml
而不是
application.yml?
Nacos Config
的相关配置都写在一个
bootstrap.yml
文件里,但是为什么要使用
bootstrap.yml
呢?使用 application.yml不可以吗?
这是其实是因为
bootstrap.yml
会被优先读取,也就是说如果项目里同时存在一个
bootstrap.yml
和一个application.yml的话,那么
bootstrap.yml
将会优先于
application.yml
被
Spring Boot
读取。这样才能实现连接外部的配置管理服务器,从远程读取一些必要的配置,避免项目在启动时缺失必要配置项而导致启动失败。
3
)创建启动类
Service1Application
在
src
下创建
com.example
包,在包中创建
Service1Application
启动类
@SpringBootApplication
public class Service1Application {
public static void main(String[] args) {
SpringApplication.run(Service1Application.class, args);
}
}
4
)创建控制器类
ConfigController
在
com.example
包下创建
controller
包,在
controller
包中创建控制器类
ConfigController
,实现获取配置信息
@RestController
@RequestMapping("/config")
public class ConfigController {
@Value("${common.name}")
private String config;
@RequestMapping(value = "/get")
public String getConfig() {
return config;
}
}
5
)测试
测试请求地址:
http://localhost:8081/config/get
测试响应结果
service1 config
3.3 支持配置动态刷新
3.3.1 测试修改nacos配置
进入
nacos
配置管理界面,测试修改
nacos
配置中心的配置后
,
能否获取最新配置
· 编辑
service1.yml
配置,修改为如下
· 测试获取配置
测试请求地址:
http://localhost:8081/config/get
测试响应结果,请求获取配置后发现并没有获取到最新配置
service1 config
为什么修改后获取不到最新配置呢?
当使用
spring
的注解
@Value
的时候
,
我们发现
,
在配置中心修改了配置文件的内容
,
但是通过注解读取出来的内容没变.
这是什么原因呢
?
其实
,
配置文件修改了内容以后
,
他是通知了服务端的
,
之所以没改
,
是因为@Value
注解获取属性会缓存
.
那么如果想动态获取修改后的配置文件怎么办呢
?
3.3.2 配置的动态刷新
如果想动态获取修改后的配置文件,在控制器中需要注入配置文件上下文来获取最新的配置信息。
在
service1
中创建控制器
ConfigController2
@RestController
@RequestMapping("/config2")
public class ConfigController2 {
// 注入配置文件上下文
@Autowired
private ConfigurableApplicationContext applicationContext;
@RequestMapping("get")
public String getConfig() {
return applicationContext.getEnvironment().getProperty("common.name");
}
}
再次测试
1
)先重启服务,测试获取配置
2
)然后修改
nacos
配置信息,最后再进行测试,则可以动态获取修改后的配置信息。
测试地址:
http://localhost:8081/config2/get
测试结果:
service1 config new2
3.4 小结
在实际进行分布式部署
service1
微服务时,会部署多个实例,每个实例的配置信息都是一致的,从
nacos配置管理中心获取即可,这样保证了多个实例使用的都是同一个配置,修改时只需要修改一处即可。