Nacos服务注册和配置中心
Nacos的定位
1、Nacos简介
官网地址:Nacos 快速开始
为什么叫Nacos这个名字?Nacos: Dynamic Naming and Configuration Service
前四个字母分别为Naming和Configuration的前两个字母,最后的s为Service
Nacos 是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
Nacos就是注册中心加上配置中心的组合就跟Consul对应的。
Nacos 的关键特性包括:
服务发现和服务健康监测;
动态配置服务;
动态 DNS 服务;
服务及其元数据管理;
各种注册中心的比较:
2、下载和安装(Windows)
GitHub上nacos-server-2.2.3的下载地址:nacos-server-2.2.3.zip (github.com)
下载完成后解压,进入bin目录打开命令框使用以下代码运行:
startup.cmd -m standalone
浏览器输入http://10.2.142.251:8848/nacos/index.html进入本地的Nacos首页。
3、Nacos Discovery服务注册中心
官网文档:Nacos 融合 Spring Cloud,成为注册配置中心 | Nacos
我们新建基于Nacos的服务提供者,新建module名称为cloudalibaba-provider-payment9001
3.1、服务提供者cloudalibaba-provider-payment9001
导入依赖
<dependencies>
<!--nacos-discovery-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 引入自己定义的api通用包 -->
<dependency>
<groupId>com.zm.cloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--SpringBoot通用依赖模块-->
<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>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
<scope>provided</scope>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
配置文件yml
server:
port: 9001
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848 #配置Nacos地址
主启动类
@SpringBootApplication
@EnableDiscoveryClient
public class Main9001 {
public static void main(String[] args) {
SpringApplication.run(Main9001.class,args);
}
}
业务类
@RestController
public class PayAlibabaController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/pay/nacos/{id}")
public String getPayInfo(@PathVariable("id") Integer id)
{
return "nacos 服务注册中心, serverPort: "+ serverPort+"\t id"+id;
}
}
启动9001到控制台看到服务管理中服务列表
浏览器输入localhost:9001/pay/nacos/111
3.2、服务消费者
新建cloudalibaba-consumer-nacos-order83的module
POM文件添加依赖
<dependencies>
<!--nacos-discovery-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--loadbalancer-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!--web + actuator-->
<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>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
配置文件yml
server:
port: 83
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
#消费者将要去访问的微服务名称(nacos微服务提供者叫什么你写什么)
service-yrl:
nacos-user-service: http://nacos-payment-provider
主启动类
@SpringBootApplication
@EnableDiscoveryClient
public class Main83 {
public static void main(String[] args) {
SpringApplication.run(Main83.class,args);
}
}
业务类
RestTemplateConfig实例化能负载均衡。
@Configuration
public class RestTemplateConfig {
//实例化 RestTemplate 实例
@Bean
@LoadBalanced //开负载均衡
RestTemplate restTemplate(){
return new RestTemplate();
}
}
OrderNacosController
@RestController
public class OrderNacosController {
@Resource
private RestTemplate restTemplate;
@Value("${service-url.nacos-user-service}")
private String serverURL;
@GetMapping("/consumer/pay/nacos/{id}")
public String paymentInfo(@PathVariable("id") Integer id){
String result = restTemplate.getForObject(serverURL + "/pay/nacos/" + id, String.class);
return result+"\t"+"我是OrderNacosController83调用者。。。。。。";
}
}
测试,启动83消费者访问nacos控制台
入驻成功,浏览器输入localhost:83/consumer/pay/nacos/111
3.3、负载均衡
我们需要两个服务提供者,要么你就复制原来的9001,要么就使用idea拷贝虚拟端口进行映射就改一改端口就可以再开一个。
然后改名字改端口
然后就可以直接启动9002了,到nacos查看9002进去了没有
看到nacos-payment-provider实例有2个就入驻成功了,访问localhost:83/consumer/pay/nacos/111,看到端口号在交替着变化就说明负载均衡可以了。
4、Nacos Config服务配置中心
之前的consul的服务配置动态变更功能可以被Nacos替代,我们可以通过Nacos和spring-cloud-starter-alibaba-nacos-config实现中心化全局配置的动态变更。
官方话:
Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。
4.1、新建cloudalibaba-config-nacos-client3377
新建cloudalibaba-config-nacos-client3377添加依赖坐标
<dependencies>
<!--bootstrap-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--nacos-config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--nacos-discovery-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--web + actuator-->
<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>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
配置yml一个是application.yml用于本地自己的配置,一个是bootstrap.yml用于从配置中心进行配置拉取
Nacos同Consul一样,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动,为了满足动态刷新和全局广播通知springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于application。
bootstrap.yml
#nacos配置
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 #nacos服务注册中心地址
config:
server-addr: localhost:8848 #nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
# nacos端配置文件DataId的命名规则是:
# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
# 本案例的DataID是:nacos-config-client-dev.yaml
application.yml
server:
port: 3377
spring:
profiles:
active: dev # 表示开发环境
#active: prod # 表示生产环境
#active: test # 表示测试环境
主启动类
@SpringBootApplication
@EnableDiscoveryClient
public class Main3377 {
public static void main(String[] args) {
SpringApplication.run(Main3377.class,args);
}
}
业务类
@RestController
@RefreshScope //在控制器类加入@RefreshScope注解使当前类下的配置支持Nacos的动态刷新功能。
public class NacosConfigClientController {
@Value("${config.info}")
private String configInfo; //这个要从服务配置中心拿来
@GetMapping("/config/info")
public String getConfigInfo(){
return configInfo;
}
}
4.2、Nacos中的匹配规则
在 Nacos Spring Cloud 中,dataId
的完整格式如下:
${prefix}-${spring.profiles.active}.${file-extension}
prefix
默认为spring.application.name
的值,也可以通过配置项spring.cloud.nacos.config.prefix
来配置。spring.profiles.active
即为当前环境对应的 profile。 注意:当spring.profiles.active
为空时,对应的连接符-
也将不存在,dataId 的拼接格式变成${prefix}.${file-extension}
file-exetension
为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension
来配置。目前只支持properties
和yaml
类型。通过 Spring Cloud 原生注解
@RefreshScope
实现配置自动更新
到nacos的配置管理中创建配置。
启动服务测试,浏览器输入localhost:3377/config/info
再修改一下nacos中的yaml配置文件,刷新一下请求就会发现配置已经刷新了。
刷新一下配置内容就更改了
历史配置
Nacos会记录配置文件的历史版本默认保留30天,此外还有一键回滚功能,回滚操作将会触发配置更新,选择指定历史信息还能进行回滚。
5、Nacos数据模型之Namespace-Group-Datald
多环境多项目管理
实际开发中,通常一个系统会准备:
dev开发环境
test测试环境
prod生产环境。
如何保证指定环境启动时服务能正确读取到Nacos上相应环境的配置文件呢?我们现在是直接在application配置文件中修改环境。
一个大型分布式微服务系统会有很多微服务子项目,每个微服务项目又都会有相应的开发环境、测试环境、预发环境、正式环境......
那怎么对这些微服务配置进行分组和命名空间管理呢?
官网上的说明
Namespace+Group+Datald三者关系?
说明:
1 是什么 | 类似Java里面的package名和类名,最外层的Namespace是可以用于区分部署环境的,Group和DataID逻辑上区分两个目标对象 |
---|---|
2 默认值 | 默认情况:Namespace=public,Group=DEFAULT_GROUPNacos默认的命名空间是public,Namespace主要用来实现隔离。比方说我们现在有三个环境:开发、测试、生产环境,我们就可以创建三个Namespace,不同的Namespace之间是隔离的。Group默认是DEFAULT_GROUP,Group可以把不同的微服务划分到同一个分组里面去 |
Service就是微服务 | 一个Service可以包含一个或者多个Cluster(集群),Nacos默认Cluster是DEFAULT,Cluster是对指定微服务的一个虚拟划分。见下一节:服务领域模型-补充说明 |
5.1、三种方案加载配置
5.1.1、DataID方案
指定spring.profile.active和配置文件的DatalD来使不同环境下读取不同的配置
使用默认空间public+默认分组DEFAULT_GROUP+新建DatalD
新建test配置DataID
然后把application文件中的test注释打开
server:
port: 3377
spring:
profiles:
#active: dev # 表示开发环境
#active: prod # 表示生产环境
active: test # 表示测试环境
重启3377测试
你配置什么就加载什么,改一下test的内容再刷新看动态刷新也是能用的
5.1.2、Group方案
通过Group实现环境区分,在默认空间public+新建PROD_GROUP+新建DatalD,我们新建nacos-config-client-prod.yaml,新建的时候顺便就创建PROD_GROUP了,不需要添加什么东西就直接把原来的 DEFAULT_GROUP删除换成PROD_GROUP就好了。
修改bootstrap配置文件,在config下增加一条group的配置即可。
#nacos配置
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 #nacos服务注册中心地址
config:
server-addr: localhost:8848 #nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
group: PROD_GROUP
application配置文件中修改环境。
然后重启测试
还是你配置什么就是什么
5.1.3、Namespace方案
通过Namespace实现命名空间环境区分。
新建Namespace: Prod_Namespace;
新建但是不填命名空间的ID它会自动生成Namespace: Prod2_Namespace;
最后你不填的就会自动生成一个串
Prod_Namespace+PROD_GROUP+DataID(nacos-config-client-prod.yaml)
新建一个配置nacos-config-client-prod.yaml,group填PROD_GROUP
在bootstrap配置文件中的config下面增加一条namespace
#nacos配置
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 #nacos服务注册中心地址
config:
server-addr: localhost:8848 #nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
group: PROD_GROUP
namespace: Prod_Namespace
application中的prod环境不变,重启3377测试
我们配置的内容已经生效。