一、什么是Nacos
Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。帮助您更敏捷和容易地构建、交付和管理微服务平台。 它是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。更详细的内容见Nacos文档
二、下载、安装及配置
安装方式多且简单,详细参考文档,启动了以后,怎么访问,怎么操作控制台,不做赘述,但凡…嗯。
三、作为注册中心
主流的注册中心产品除了当前要介绍的Nacos,常用的还有Eureka、Consul、CoreDNS、Zookeeper等,先给对比一番,简单了解:
Nacos | Eureka | Consul | Zookeeper | CoreDNS | |
---|---|---|---|---|---|
一致性协议 | CP+AP | AP | CP | CP | — |
健康检查 | TCP/HTTP/MYSQL/Client Beat | Client Beat | TCP/HTTP/gRPC/Cmd | Keep Alive | — |
负载均衡策略 | 权重/metadata/Selector | Ribbon | Fabio | — | RoundRobin |
雪崩保护 | 有 | 有 | 无 | 无 | 无 |
自动注销实例 | 支持 | 支持 | 支持 | 支持 | 不支持 |
访问协议 | HTTP/DNS | HTTP | HTTP/DNS | TCP | DNS |
监听支持 | 支持 | 支持 | 支持 | 支持 | 不支持 |
多数据中心 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
跨注册中心同步 | 支持 | 不支持 | 支持 | 不支持 | 不支持 |
SpringCloud集成 | 支持 | 支持 | 支持 | 支持 | 不支持 |
Dubbo集成 | 支持 | 不支持 | 支持 | 支持 | 不支持 |
Kubernates集成 | 支持 | 不支持 | 支持 | 不支持 | 支持 |
粗略一看,Nacos多方面特点明显,没有历史包袱的话,用就完了。
1、依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${latest.version}</version>
</dependency>
2、在application.properties中配置注册中心的地址和应用名
# 服务名称必须存在,否则不能注册到注册中心,将来就要靠服务名去发现服务的
spring.application.name=mail-coupon
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
3、@EnableDiscoveryClient开启服务注册发现功能
/**
* @author zhangxs
* @date 2021-05-15 21:29
*/
@EnableDiscoveryClient
@SpringBootApplication
public class MailCouponApplication {
public static void main(String[] args) {
SpringApplication.run(MailCouponApplication.class, args);
}
}
说明:服务发现,远程调用在后续OpenFeign专题中会提到。
四、作为配置中心
1、依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>${latest.version}</version>
</dependency>
2、在bootstrap.properties中配置配置中心的地址和应用名
spring.application.name=coupon-product
spring.cloud.nacos.server-addr=127.0.0.1:8848
# 也可以配置指定的命名空间,默认是public命名空间
说明:之所以需要配置spring.application.name,是因为它是构成Nacos配置管理dataId字段的一部分。在Nacos Spring Cloud中,dataId的完整格式如下:
${prefix}-${spring.profiles.active}.${file-extension}
- prefix 默认为spring.application.name的值,也可以通过配置项spring.cloud.nacos.config.prefix来配置。
- spring.profiles.active即为当前环境对应的 profile,详情可以参考Spring Boot文档。 注意:当spring.profiles.active为空时,对应的连接符 - 也将不存在,dataId的拼接格式变成
${prefix}.${file-extension}
即应用名.properties或应用名.yml - file-exetension为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension来配置。目前只支持properties和yml类型。
3、在应用名.properties/yml中添加配置
coupon.user.name=xiaosheng
coupon.user.age=18
4、动态获取配置,且支持自动刷新
/**
* 相关注解说明:
* -- @RefreshScope:动态获取并刷新配置
* -- @Value:获取到配置
* 说明:如果配置中心和当前应用的配置文件中配置了相同的项,优先使用配置中心的配置
* @author zhangxs
* @date 2021-05-15 21:29
*/
@RefreshScope
@RestController
@RequestMapping("/coupon")
public class CouponController {
@Value("${coupon.user.name}")
private boolean name;
@Value("${coupon.user.age}")
private boolean age;
@GetMapping("/get")
public String get() {
return name + "的年龄为:" + age;
}
}
5、配置中心使用细节
- 命名空间、配置隔离:默认的public命名空间是保留空间,默认新增的所有配置都在public命名空间下。通常情况下,配置隔离可以基于开发、测试、生产环境,利用命名空间做环境隔离,也可以基于微服务做配置隔离,每个微服务都创建自己的命名空间,只加载自己命名空间下的配置。如果需要做配置隔离,在bootstrap.properties下指定相应命名空间的ID
spring.cloud.nacos.config.namespace=174047ec-2312-434c-9c39-747e7e188bd8
。要在项目中使用哪种配置隔离方案,自行根据实际情况决定即可。 - 配置集:所有配置的集合
- 配置集ID:就是dataId,类似于文件名
- 配置分组:默认所有的配置集都属于DEFAULT_GROUP,可以自定义组,比如双十一,双十二特有配置组,配置好组之后,配置文件中需要指定组
spring.cloud.nacos.config.group=1111
。 - 同时加载多个配置集:
比如将原本的配置文件分为datasource.yml、mybatis.yml、other.yml多个配置文件,看如下bootstrap.properties中的部分配置:
# 配置文件ID,即配置文件名
spring.cloud.nacos.config.extension-configs[0].data-id=datasource.yml
# 指定组
spring.cloud.nacos.config.extension-configs[0].group=dev
# 默认不自动刷新
spring.cloud.nacos.config.extension-configs[0].refresh=true
# 配置文件ID,即配置文件名
spring.cloud.nacos.config.extension-configs[1].data-id=mybatis.yml
# 指定组
spring.cloud.nacos.config.extension-configs[1].group=dev
# 默认不自动刷新
spring.cloud.nacos.config.extension-configs[1].refresh=true
# 配置文件ID,即配置文件名
spring.cloud.nacos.config.extension-configs[2].data-id=other.yml
# 指定组
spring.cloud.nacos.config.extension-configs[2].group=dev
# 默认不自动刷新
spring.cloud.nacos.config.extension-configs[2].refresh=true