Nacos 简介
Nacos (Dynamic Naming and Configuration Service) 定位为:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它不仅是注册中心组件,还包含配置中心功能。
本文详细介绍了 Nacos 作为 Spring Cloud Alibaba 核心组件的安装与使用方法。内容包括 Windows 和 Linux 单机版安装步骤,Spring Cloud 集成配置,服务注册与发现流程,以及负载均衡策略(权重配置、同集群优先)。此外,还讲解了健康检查机制、环境隔离(Namespace)配置、配置中心的热更新功能,并对比了 Nacos 与 Eureka 在功能、CAP 理论和发现模式上的区别。

Nacos (Dynamic Naming and Configuration Service) 定位为:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它不仅是注册中心组件,还包含配置中心功能。
截至目前,Nacos 几乎支持了所有的主流语言,比如 Java, Go, C++, Nodejs, Python, Scala 等。
Nacos 官网:https://nacos.io/ Nacos 仓库:https://github.com/alibaba/nacos
学习阶段采用单机安装即可。
目前官方推荐的稳定版本为 2.2.3。
把压缩包解压到任意非中文的目录下。
目录介绍:
Nacos 默认启动方式为集群,启动前需要修改配置为单机模式。
启动非常简单,进入 bin 目录下,双击 startup.cmd 即可。
访问 Nacos 主页,出现以下界面,表示 Nacos 启动成功:http://127.0.0.1:8848/nacos
Nacos 启动后,目录下会多一个 logs 的文件夹,报错日志在:logs/nacos.log。 常见问题会有集群模式启动和端口号冲突两种报错。
解决方式有以下两种:
netstat -ano | findstr "8848"
c. 杀掉进程
taskkill /pid 4968 /F
上传提前下载好的安装包到服务器上某个目录,比如 /usr/local/src。 解压安装包:
unzip nacos-server-2.2.3.zip
如果第一次使用,未安装 unzip 命令,需要安装一下 apt-get install unzip
解压后目录与 windows 版相同。
进入 nacos/bin 目录,输入命令:
bash startup.sh -m standalone
上述命令为 Ubuntu 系统的命令 nacos 安装前需要先安装 JDK CentOS 使用:sh startup.sh -m standalone
启动成功后,访问 Nacos 链接:http://IP:port/nacos
Nacos 是 Spring Cloud Alibaba 的组件,Spring Cloud Alibaba 遵循 Spring Cloud 中定义的服务注册、服务发现规范。因此使用 Nacos 和使用 Eureka 对于微服务来说,并没有太大区别。 主要差异在于:
Nacos 的服务注册和服务发现代码一样。
引入 Spring Cloud Alibaba 依赖,在父工程的 pom 文件中引入:
<properties>
<spring-cloud-alibaba.version>2022.0.0.0-RC2</spring-cloud-alibaba.version>
</properties>
<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 Boot 和 Spring Cloud 的版本是有一定对应关系的。Spring Cloud Alibaba 也遵循 Spring Cloud 的标准,在引入依赖时,一定要确认各个版本的对应关系。Spring Cloud Alibaba 和 Spring Cloud 版本对应关系,参考官方文档:https://sca.aliyun.com/zh-cn/docs/2022.0.0.0/overview/version-explain/ 版本在一定范围内可以自由选择
引入 Nacos 依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
引入 Load Balance 依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
文章中使用本地服务器地址。
| 配置项 | Key | 默认值 | 说明 |
|---|---|---|---|
| 服务端地址 | spring.cloud.nacos.discovery.server-addr | 无 | Nacos Server 启动监听的 ip 地址和端口 |
spring:
application:
name: product-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
public OrderInfo selectOrderById(Integer orderId){
OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
String url = "http://product-service/product/" + orderInfo.getProductId();
ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
orderInfo.setProductInfo(productInfo);
return orderInfo;
}
@Configuration
public class BeanConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
启动两个服务,观察 Nacos 的管理界面,发现 order-service 和 product-service 都注册在 Nacos 上了。
启动三个 product-service 服务。
观察 Nacos 控制台:
生产环境相对是比较恶劣的,我们需要对服务的流量进行更加精细的控制。Nacos 支持多种负载均衡策略,包括权重、同机房、同地域、同环境等。
当某一个节点上接口的性能较差时,我们可以第一时间对该节点进行下线。 操作步骤:服务详情 -> 下线。
点击下线后,再次请求接口,会发现该服务没有请求进来了。 再次单击上线,该节点会继续收到请求。
除了下线之外,我们也可以配置这个节点的流量权重。
操作步骤:找到对应节点 -> 编辑 -> 在弹出的窗口修改权重值。 每个节点默认权重为 1,修改为 0.1。
由于 Spring Cloud LoadBalance 组件自身有负载均衡配置方式,所以不支持 Nacos 的权重属性配置。我们需要开启 Nacos 的负载均衡策略,让权重配置生效。
# 开启 nacos 的负载均衡策略
spring.cloud.loadbalancer.nacos.enabled=true
spring:
cloud:
loadbalancer:
nacos:
enabled: true
启动服务,访问多次接口,观察结果,会发现 9091 端口号的实例接收的请求明显比另外两个实例少。
整体流量生效,局部流量不是严格按照设置的比例进行分配的
修改权重时,可能会报错:
报错信息:caused: errCode: 500, errMsg: do metadata operation failed ;caused:com.alibaba.nacos.consistency.exception.ConsistencyException: The Raft Group[naming_instance_metadata] did not find the Leader node...
原因:Nacos 采用 raft 算法来计算 Leader,并且会记录前一次启动的集群地址,当服务器 IP 改变时会导致 raft 记录的集群地址失效,导致选 Leader 出现问题。(网络环境发生变化时,IP 地址也会发生变化) 解决办法:删除 Nacos 根目录下 data 文件夹下的 protocol 文件夹即可。
Nacos 把同一个机房内的实例,划分为一个集群。所以同集群优先访问,在一定程度上也可以理解为同机房优先访问。 微服务架构中,一个服务通常有多个实例共同提供服务,这些实例可以部署在不同的机器上,这些机器可以分布在不同的机房。
微服务访问时,应尽量访问同机房的实例。当本机房内实例不可用时,才访问其他机房的实例。通常情况下,因为同一个机房的机器属于一个局域网,局域网访问速度更快一点。
spring:
cloud:
nacos:
discovery:
server-addr: 110.41.51.65:10020
cluster-name: SH # 集群名称:上海集群
重启服务,观察 Nacos 控制台,SH 集群下多了一个实例。
复制 product-service 启动配置,添加 VM Option。 设置 9091 端口号的实例,机房为 BJ:
-Dserver.port=9091 -Dspring.cloud.nacos.discovery.cluster-name=BJ
设置 9092 端口号的实例,机房为 BJ:
-Dserver.port=9092 -Dspring.cloud.nacos.discovery.cluster-name=BJ
观察 Nacos,BJ 集群下多了一个实例。
spring:
cloud:
nacos:
discovery:
server-addr: 110.41.51.65:10020
cluster-name: SH # 集群名称:上海集群
同权重配置:
# 开启 nacos 的负载均衡策略
spring.cloud.loadbalancer.nacos.enabled=true
spring:
cloud:
loadbalancer:
nacos:
enabled: true
启动服务。
Nacos 作为注册中心,需要感知服务的健康状态,才能为服务调用方提供良好的服务。Nacos 中提供了两种健康检查机制:
客户端主动上报机制:
服务器端反向探测机制:
比如领导管理员工的工作
- 员工主动汇报:员工每天主动汇报自己工作进度
- 领导主动问询:领导每周向员工了解工作进度
Nacos 中的健康检查机制不能主动设置,健康检查机制是和 Nacos 的服务实例类型强相关的。
Nacos 的服务实例 (注册的节点) 分为临时实例和非临时实例。
Nacos 对临时实例,采取的是 客户端主动上报机制,对非临时实例,采取服务器端反向探测机制。
配置一个服务实例为永久实例:
spring:
cloud:
nacos:
discovery:
ephemeral: false # 设置为非临时实例
重启服务,观察 Nacos 控制台。 停止服务,再观察控制台:节点依然不会消失。
设置服务实例类型,重新启动 Nacos 可能会报错。 原因:Nacos 会记录每个服务实例的 IP 和端口号,当发现 IP 和端口都没有发生变化时,Nacos 不允许一个服务实例类型发生变化,比如从临时实例,变为非临时实例,或非临时实例,变成临时实例。
解决办法:
企业开发中,一个服务会分为开发环境,测试环境和生产环境。
通常情况下,这几个环境是不能互相通信的。Nacos 提供了 namespace(命名空间) 来实现环境的隔离。不同的 namespace 的服务不可见。
默认情况下,所有服务都在同一个 namespace,名为 public。 点击左侧命名空间,可以对 namespace 进行操作。 新增命名空间。
namespace 创建完成后,对服务进行配置。
| 配置项 | Key | 默认值 | 说明 |
|---|---|---|---|
| 命名空间 | spring.cloud.nacos.discovery.namespace | 无 | 常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。 |
修改 order-service 的命名空间:
spring:
cloud:
nacos:
discovery:
namespace: 51152a13-7911-49e3-bbdc-16fd5670a257
启动服务,观察 Nacos 控制台 public 命名空间下只有 product-service 服务。 order-service 在 dev 命名空间下。
访问接口,测试远程调用。
修改 product-service 的一个实例,命名空间改为 dev:
spring:
cloud:
nacos:
discovery:
namespace: 51152a13-7911-49e3-bbdc-16fd5670a257
除了注册中心和负载均衡之外,Nacos 还是一个配置中心,具备配置管理的功能。Namespace 的常用场景之一是不同环境的配置区分隔离。例如开发测试环境和生产环境的配置隔离。
当前项目的配置都在代码中,会存在以下问题:
配置中心就是对这些配置项进行统一管理。通过配置中心,可以集中查看、修改和删除配置,无需再逐个修改配置文件。提高效率的同时,也降低了出错的风险。
通过以下操作,我们先来感受下 Nacos 配置中心的使用。 参考文档:https://nacos.io/docs/next/ecology/use-nacos-with-spring-cloud/
在 Nacos 控制台添加配置项。 新建配置项。 配置内容:
nacos.test.num=5
说明:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud2020.*之后版本需要引入 bootstrap-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
spring.application.name=product-service
spring.cloud.nacos.config.server-addr=110.41.51.65:10020
或者使用 bootstrap.yml:
spring:
application:
name: product-service
cloud:
nacos:
config:
server-addr: 110.41.51.65:10020
spring.application.name 需要和 nacos 配置管理的 Data ID 一致。 spring.cloud.nacos.config.server-addr 为 Nacos Server 的地址。
配置中心和注册中心的配置是隔离的 Nacos 配置中心:spring.cloud.nacos.config.server-addr Nacos 注册中心:spring.cloud.nacos.discovery.server-addr
@RequestMapping("/config")
@RefreshScope
@RestController
public class NacosController {
@Value("${nacos.test.num:0}")
private Integer nacosNum;
@RequestMapping("/get")
public Integer get(){
return nacosNum;
}
}
Nacos 配置管理的命名空间和服务列表的命名空间是分别设置的。默认是 public。 Nacos 命名空间配置依然在 bootstrap.properties 中进行配置。
spring.cloud.nacos.config.namespace=51152a13-7911-49e3-bbdc-16fd5670a257
对应 bootstrap.yml 配置:
spring:
cloud:
nacos:
config:
namespace: 51152a13-7911-49e3-bbdc-16fd5670a257
value 对应 命名空间的 ID。 如果设置命名空间后,项目启动时,会从该命名空间下找对应的配置项。
Data Id 格式介绍
在 Nacos Spring Cloud 中,dataId 的完整格式如下:
${prefix}-${spring.profiles.active}.${file-extension}
微服务启动时,会从 Nacos 读取多个配置文件:
${spring.application.name}, ${spring.profiles.active} 等通过配置文件来指定时,必须放 bootstrap.properties 文件中。
在 bootstrap.yml 中添加 spring.profiles.active 值:
spring:
profiles:
active: dev
三个文件的优先级为:product-service-dev.properties > product-service.properties > product-service。 也就是说 接口:http://127.0.0.1:9090/config/get 会以上面的优先级顺序读取对应文件中的值。
共同点:
区别:
本文介绍了 Nacos 作为注册中心与配置中心的核心功能及实践方法。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online