一、Nacos简介
1.1、为什么叫Nacos?
前四个字母分别为Naming和Configuration的前两个字母,最后的s为Service。
1.2、是什么?
一个更易于构建云原生应用的动态服务发现,配置管理和服务管理中心
Nacos就是注册中心+配置中心的组合
1.3、能干嘛?
替代Eureka做服务注册中心
替代Config做微服务配置中心
二、安装并运行Nacos
进入Nacos的官网下载,地址:http://nacos.io
- 启动,打开nacos/bin,windows环境下点击startup.cmd启动nacos

- 启动后访问localhost:8848/nacos启动nacos



三、Nacos作为服务注册中心演示
3.1、创建基于Nacos的服务提供者
1、新建Module
新建cloudalibaba-provider-payment9001
2、引入依赖
1 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
| <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.1.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> </dependencies>
|
3、编写yml配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| server: port: 9001 spring: application: name: nacos-payment-provider cloud: nacos: discovery: server-addr: localhost:8848 management: endpoints: web: exposure: include: '*'
|
4、主启动类
在需要注册入注册中心的模块主启动类上添加@EnableDiscoveryClient注解
1 2 3 4 5 6 7 8
| @EnableDiscoveryClient @SpringBootApplication public class PaymentMain9001 { public static void main(String[] args) { SpringApplication.run(PaymentMain9001.class,args); System.out.println("http://localhost:8848/nacos"); } }
|
5、业务类
1 2 3 4 5 6 7 8 9 10
| @RestController public class PaymentController { @Value("${server.port}") private String serverPort;
@GetMapping(value = "/payment/nacos/{id}") public String getPayment(@PathVariable("id") Integer id) { return "nacos registry, serverPort: "+ serverPort+"\t id"+id; } }
|
6、启动9001微服务,查看nacos控制台

7、仿照9001创建9002微服务,启动查看结果

3.2、创建基于Nacos的服务消费者
1、新建Module
新建cloudalibaba-consumer-nacos-order83
2、引入依赖
1 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
| <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.cloudstudy</groupId> <artifactId>common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
|
为什么Nacos支持负载均衡?

3、编写yml配置文件
1 2 3 4 5 6 7 8 9 10 11 12
| server: port: 83 spring: application: name: nacos-order-consumer cloud: nacos: discovery: server-addr: localhost:8848
service-url: nacos-user-service: http://nacos-payment-provider
|
4、主启动类
1 2 3 4 5 6 7
| @EnableDiscoveryClient @SpringBootApplication public class OrderNacosMain83 { public static void main(String[] args) { SpringApplication.run(OrderNacosMain83.class,args); } }
|
5、业务类
OrderNacosController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @RestController @Slf4j public class OrderNacosController { @Resource private RestTemplate restTemplate;
@Value("${service-url.nacos-user-service}") private String serverURL;
@GetMapping(value = "/consumer/payment/nacos/{id}") public String paymentInfo(@PathVariable("id") Long id) { return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class); }
}
|
ApplicationContextConfig
1 2 3 4 5 6 7 8
| @Configuration public class ApplicationContextConfig{ @Bean @LoadBalanced public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
|
6、启动83微服务,查看nacos控制台

7、使用83消费者调用服务提供方
访问http://localhost:83/consumer/payment/nacos/13


这样就实现了负载均衡和远程调用
3.3、各种服务注册中心对比
1、Nacos全景图

2、Nacos和CAP

四、Nacos作为服务配置中心演示
4.1、Nacos作为配置中心–基础配置
1、新建Module
创建微服务模块:cloudalibaba-config-nacos-client3377
2、引入依赖
1 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
| <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency>
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
|
3、编写yml配置文件
bootstrap.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| server: port: 3377
spring: application: name: nacos-config-client cloud: nacos: discovery: server-addr: localhost:8848 config: server-addr: localhost:8848 file-extension: yaml
|
application.yml
1 2 3 4
| spring: profiles: active: dev
|
为何编写两个配置文件?
Nacos同Spring Cloud Config一致,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置后,才能保证项目的正常启动。
Spring Boot中配置文件的加载是存在优先级顺序的,bootstrap(全局)优先级高于application(自定义)
4、主启动类
1 2 3 4 5 6 7 8
| @EnableDiscoveryClient @SpringBootApplication public class NacosConfigClientMain3377 { public static void main(String[] args) { SpringApplication.run(NacosConfigClientMain3377.class, args); } }
|
5、业务类
@RefreshScope注解用于动态刷新,作用在Controller层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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;
@RestController @RefreshScope public class ConfigClientController { @Value("${config.info}") private String configInfo;
@GetMapping("/config/info") public String getConfigInfo() { return configInfo; } }
|
6、Nacos的配置规则
- 理论:Nacos中的dataid的组成格式与SpringBoot配置文件中的匹配规则
说明:之所以要配置spring.application.name ,示音为它是构成Nacos配置管理dataId字段的一部分。
在Nacos Spring Cloud中,dataId的完整格式如下
1
| ${prefix}-${spring.profile.active}.${file-extension}
|
- prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix 来配置。
- spring.profile.active 即为当前环境对于的profile,详情可以参考 Spring Boot文档 注意:当spring.profile.active 为空时,对应的 - 也将不存在,此时dataId的拼接格式变为 ${prefix}-${file-extension} ,file-extension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置,目前只支持properties 和 yaml 类型。
- 通过Spring Cloud原生注解 @RefreshScope 实现配置自动更新。
最后公式为:
1
| ${spring.application.name}-${spring.profile.active}.${file-extension}
|
根据上面的公式,我们可以得到cloudalibaba-config-nacos-client3377微服务配置的dataId为:nacos-config-client-dev.yaml
7、实操
在nacos控制台中选择配置管理-配置列表,点击“+”号添加配置

添加的配置如下:

8、测试
运行cloudalibaba-config-nacos-client3377微服务,调用接口查看配置信息,接口地址为:http://localhost:3377/config/info

9、配置的动态刷新
修改下Nacos中的yaml配置文件,再次调用查看配置的端口,就会发现配置已经刷新。

重新调用查看配置的接口,查看配置

4.2、Nacos作为配置中心–分类配置
1、问题一
实际开发中,通常一个系统会准备
如何保证指定环境启动时服务能正确读取到Nacos上相应环境的配置文件呢?
2、问题二
一个大型分布式微服务系统会有很多个微服务子项目
每个微服务又有对应的开发环境、预发环境、测试环境、正式环境…
那么又怎么对这些配置进行处理呢?
3、什么是分类配置?
类似Java中的package + 类名
最外层的namespace用于区别部署环境,Group和DataId从逻辑上区分两个对象

默认情况下
- Namespace=public
- Group=DEFAULT_GROUP
Nacos默认的命名空间为public,Namespace主要用来隔离,比如说我们有三个(生产、开发、测试)环境,那么我们就可以创建三个Namespace,不同的Namespace之间是隔离的。
Group默认是DEFAULT_GROUP,Group可以把不同微服务划分到一个分组中。
Service就是微服务,一个Service可以包括多个Cluster(集群),Nacos默认Cluster是Default,Cluster是对指定微服务的一个虚拟划分。
比如说为了容灾,将Service微服务分别部署在了杭州机房和广州机房,这个时候给杭州机房的Service微服务起一个集群名称(HZ),给广州计方的Service微服务起一个集群名称(GZ),还可以尽量让同一个机房中的微服务相互调用,提升性能。
Instance:微服务实例
4、通过DataId读取不同配置
默认空间+默认分组+新建dev和test两个DataId

- 修改3377微服务的application.yml配置文件,指定记载环境
1 2 3 4 5 6
| spring: profiles: active: test
|
此时读取的配置的DataId为 nacos-config-client-test.yaml ,配置为


5、通过Group读取不同配置
新建一个开发组DEV_GROUP

新建一个测试组TEST_GROUP

此时配置列表如下,两个不同组有相同DataId的配置

在bootstrap.yml配置文件中添加一条配置,指定要加载的配置组
1 2 3 4 5 6
| spring: cloud: nacos: config: group: TEST_GROUP
|
同时修改application.yml配置文件中启动的环境
1 2 3 4 5 6
| spring: profiles: active: info
|
重启3377,访问http://localhost:3377/config/info ,结果如下

修改bootstrap.yml配置文件,重启
1 2 3 4 5 6
| spring: cloud: nacos: config: group: DEV_GROUP
|
结果为:

6、通过Namespace读取不同配置
默认的namespace不能删除,新建DEV/TEST命名空间



切换到dev namespace,新建三个分组,分组中配置DataId一致。

切换namespace,在bootstrap.yml配置文件中添加如下配置,同时修改application.yml中配置环境为dev:
1 2 3 4 5
| spring: cloud: nacos: config: namespace: a9ec0b1e-e254-4b99-84ec-fa4ca62bf5a6
|

五、Nacos集群和持久化配置(重要)
5.1、官网说明
1、官网文档
https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html
2、官网架构图
VIP:virtual IP,虚拟IP,也就是nginx

3、根据官网翻译,我们可得以下架构图

4、说明
按照上面的架构图,我们需要Mysql数据库;
默认Nacos使用嵌入式数据库实现了数据的存储。所以,如果启动多个默认配置的Nacos节点,数据存储是存在一致性问题的。为了解决这个问题,Nacos采用了集中式存储的方式支持集群体部署,目前只支持MySQL的存储。
5.2、Nacos持久化配置解释
1、Nacos自带了嵌入式数据库
Nacos默认自带嵌入式数据库derby,打开Nacos的依赖坐标:https://github.com/alibaba/nacos/blob/develop/config/pom.xml

但当我们做Nacos集群时,每个Nacos都各自带着一个derby嵌入式数据库,此时会出现持久化数据不一致的问题,此时我们引入外部的MySQL数据库,将配置数据持久化到MySQL中。
2、derby到MySQL切换配置步骤
在nacos-server-1.1.4\nacos\conf目录下找到并执行 nacos-mysql.sql 脚本

在nacos-server-1.1.4\nacos\conf目录下找到application.properties,增加支持mysql数据源配置,添加mysql数据库的url、用户名和密码
注:nacos默认不支持mysql8.0,如需支持8.0,需要下载mysql8.0驱动进行更换。
1 2 3 4 5 6 7
| spring.datasource.platform=mysql
db.num=1 db.url.0=jdbc:mysql://localhost:3306/nacos_config?&connectTimeout=10000&socketTimeout=30000&serverTimezone=GMT%2B8 db.user=root db.password=tianxin1230.
|
重启Nacos,可以看到是个全新的空记录页面