跳到主要内容SpringCloud Nacos 服务注册发现与配置中心实战 | 极客日志Javajava
SpringCloud Nacos 服务注册发现与配置中心实战
Nacos 是阿里巴巴开源的动态服务发现与配置管理平台。本文涵盖 Nacos 在 Spring Cloud 中的核心应用,包括服务注册与发现机制、基于 RestTemplate 的远程调用优化、负载均衡策略配置及集群优先访问设置。此外,详细说明了健康检查模式(临时实例与非临时实例)的区别与环境隔离方案(Namespace)。最后深入解析配置中心功能,阐述 bootstrap 引导文件的作用、Data ID 构建规则及配置优先级,实现配置的集中管理与实时生效。
baireiraku1 浏览 SpringCloud Nacos 核心功能详解
0. 前言
- SpringBoot 版本:
3.2.5
- SpringCloud 版本:
2023.0.3
- SpringCloud Alibaba 版本:
2023.0.1.0
- Nacos 版本:
2.2.3
1. 概述
Nacos (Dynamic Naming and Configuration Service) 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置和管理平台。在 Spring Cloud 体系中,Nacos 为微服务架构提供服务注册与发现以及动态配置管理能力。
启动:双击 startup.cmd,默认端口号 8848。

配置:在记事本中打开 startup.cmd 文件,修改 set MODE="cluster" 为 set MODE="standalone"。

下载:Nacos GitHub Releases

2. 服务注册与发现
服务提供者 (Service Provider):在启动时,会将自己的网络地址 (IP + Port)、服务名称等信息注册到 Nacos 服务器。同时,它会定时向 Nacos 发送心跳,以证明自己'活着'。
服务消费者 (Service Consumer):在需要调用某个服务时,它会向 Nacos 服务器查询该服务的地址列表 (服务发现)。获取到列表后,消费者会根据负载均衡策略选择一个提供者进行调用。Nacos 也会在提供者列表发生变化时,实时通知消费者。
Nacos 服务器 (Nacos Server):注册中心的核心。它负责接收服务注册请求,管理所有注册的服务实例,维护服务实例的健康状态,并响应消费者的服务发现请求。

<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
添加配置:在 application.yml 中添加以下配置
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
启动服务并访问 http://127.0.0.1:8848/nacos/#/serviceManagement 观察是否注册成功。
3. 远程调用
3.1 RestTemplate
RestTemplate 是 Spring 框架提供的同步客户端 HTTP 访问的核心类,用于简化与 HTTP 服务的通信。
本项目包含两个微服务:order-service(订单服务) 和 product-service(商品服务),它们分别提供了查询订单详情和商品详情的接口。
在 order-service 的业务逻辑中,当需要查询订单信息并同时获取该订单关联的商品详情时,就必须调用 product-service 提供的接口。为了实现这一跨服务调用,我们需要借助 RestTemplate 来完成服务间的通信。
远程调用 product-service(商品服务)
@Service
public class OrderService {
private final OrderMapper orderMapper;
private final RestTemplate restTemplate;
@Autowired
public OrderService(OrderMapper orderMapper, RestTemplate restTemplate) {
this.orderMapper = orderMapper;
this.restTemplate = restTemplate;
}
public OrderInfo selectOrderById(Integer id) {
OrderInfo orderInfo = orderMapper.selectOrderById(id);
String url = "http://127.0.0.1:9000/product/getProductById?id=" + orderInfo.getProductId();
ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
orderInfo.setProductInfo(productInfo);
return orderInfo;
}
}
@Configuration
public class BeanConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
3.2 引入后 Nacos 进行远程调用
- 硬编码 IP 的 RestTemplate 调用的痛点:在代码中写死
"http://127.0.0.1:9000/product/getProductById?id=" + orderInfo.getProductId()。如果商品服务的 IP 地址变了,或者需要切换环境,必须修改代码。
- Nacos 优势:服务调用方只需知道服务提供方的服务名,Nacos 负责将服务名动态解析为具体的 IP 地址。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
为 RestTemplate 添加 @LoadBalanced 注解
@Configuration
public class BeanConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
远程调用 product-service(商品服务)
@Service
public class OrderService {
private final OrderMapper orderMapper;
private final RestTemplate restTemplate;
@Autowired
public OrderService(OrderMapper orderMapper, RestTemplate restTemplate) {
this.orderMapper = orderMapper;
this.restTemplate = restTemplate;
}
public OrderInfo selectOrderById(Integer id) {
OrderInfo orderInfo = orderMapper.selectOrderById(id);
String url = "http://product-service/product/getProductById?id=" + orderInfo.getProductId();
ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
orderInfo.setProductInfo(productInfo);
return orderInfo;
}
}
4. 负载均衡
Nacos 作为服务注册与发现中心,本身不直接提供负载均衡能力,而是与客户端负载均衡器 (如 Spring Cloud LoadBalancer) 配合使用,实现服务调用的负载均衡。
由于 Spring Cloud LoadBalancer 默认的负载均衡策略 (轮询、随机) 不会读取 Nacos 实例的权重属性。要让 Nacos 中配置的权重生效,我们需要添加配置来开启 Nacos 的负载均衡策略。
spring:
cloud:
loadbalancer:
nacos:
enabled: true
- 进入「服务管理」->「服务列表」
- 点击 product-service 服务,进入详情页
- 在实例列表中,点击实例的「编辑」按钮
- 设置「权重」值
5. 同集群优先访问
在微服务部署中,经常会将服务部署在不同的机房或区域 (如北京、上海、杭州),为了减少跨机房调用的网络延迟和成本,我们需要实现同集群优先访问的策略。
添加配置 -Dspring.cloud.nacos.discovery.cluster-name=cluster-beijing
order-service:在 yml 文件中添加如下配置
spring:
cloud:
nacos:
discovery:
cluster-name: cluster-beijing
6. 健康检查
Nacos 健康检查机制确保了服务调用始终指向健康的实例,共有两种模式。
- 客户端主动上报机制:
- 客户端通过心跳上报方式告知服务端 (Nacos 注册中心) 健康状态,默认心跳间隔 5 秒。
- Nacos 会在超过 15 秒未收到心跳后将实例设置为不健康状态,超过 30 秒将实例删除。
- 服务器端反向探测机制:
- Nacos 主动探知客户端健康状态,默认间隔为 20 秒。
- 健康检查失败后实例会被标记为不健康,不会被立即删除。
具体使用哪种模式与 Nacos 的服务实例类型强相关。
- 临时实例:采取
客户端主动上报机制。如果实例宕机超过一定时间,会从服务列表剔除,默认类型。
- 非临时实例:采取
服务器端反向探测机制。如果实例宕机,不会从服务列表剔除。
如果想要将某一服务 (如 order-service) 修改为非临时实例,需要在 yml 文件中添加如下配置。
spring:
cloud:
nacos:
discovery:
ephemeral: false
注意:由于注册到 Nacos 上的实例默认为临时实例,而 Nacos 的服务实例类型一旦确定,不能随意更改,否则会导致启动报错。
解决办法:先停止 Nacos 服务,删除 /data/protocol/raft 目录下的所有文件,里面保存的是应用实例的元数据信息,然后重启 Nacos 服务。
7. 环境隔离
在微服务架构中,环境隔离是实现多环境并行管理的关键。对于企业开发来说,一个服务一般会划分为开发环境,测试环境和生产环境。
- 开发环境:开发人员用于开发的服务器,是最基础的环境。
- 测试环境:测试人员用来进行测试的服务器,是开发环境到生产环境的过渡环境。
- 生产环境:正式提供对外服务的环境。
环境之间需要严格隔离,避免相互干扰。Nacos 提供了 namespace(命名空间) 来实现环境的隔离,不同的 namaspace 的服务不可见 (Nacos 默认提供了一个 public[保留空间])。
spring:
cloud:
nacos:
discovery:
namespace: 0bec5adc-2787-44b0-b826-e4bb48746c4e
使用 dev 环境的 order-service 服务调用 public 环境的 product-service 服务。
8. 配置中心
在微服务架构中,传统的 application 配置文件存在以下痛点:
- 修改需重启:修改配置后必须重启应用,无法动态调整配置。
- 环境管理困难:每个环境 (如 dev/test/prod) 都要维护独立的配置文件,容易出错。
- 配置集中管理:统一管理不同环境、不同服务的配置。
- 配置实时生效:配置变更后,应用可以实时感知并更新。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
8.1 bootstrap 启动文件详解
当配置文件交由 Nacos 管理后,应用程序的启动流程发生了根本性的变化。不再是简单的本地文件读取 (application.properties/application.yml),而是变成了一个 '先连接配置中心,再加载配置,最后启动应用' 的流程。
bootstrap.yml(或 bootstrap.properties) 是 Spring Cloud 应用程序的 引导配置文件,在应用程序启动时 优先于 application.yml 被加载,主要配置以下内容:
- Nacos 服务器 IP 地址:连接 Nacos 配置中心。
- 应用程序名称:作为 Data ID 的前缀,用于在 Nacos 服务器上定位到具体的配置文件。
- file-extension:指定配置文件的格式,用于正确解析。
order-service 的 bootstrap.yml 文件
spring:
application:
name: order-service
profiles:
active: local
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
namespace: 0bec5adc-2787-44b0-b826-e4bb48746c4e
file-extension: yaml
discovery:
server-addr: 127.0.0.1:8848
ephemeral: true
namespace: 0bec5adc-2787-44b0-b826-e4bb48746c4e
从 SpringCloud 2020.0.0 版本开始,Spring Cloud 默认禁用了 bootstrap 上下文,导致:
- bootstrap.yml/properties 文件不会被自动加载。
- Nacos 配置中心的配置无法自动获取。
- 启动时出现配置缺失错误。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
8.2 Data ID
在连接到 Nacos 配置中心后,应用会根据特定的规则来确定读取哪个配置文件。这个规则由 Data ID 的构建逻辑决定,Data ID 的构建公式如下:
Data ID = ${prefix} - ${spring.profiles.active} . ${file-extension}
以上述 bootstrap.yml 文件为例,order-service 服务将从 Nacos 上读取 order-service-local.yaml 配置文件。但实际启动服务时,会同时监听三个配置文件。
- order-service-local.yaml:${prefix} - ${spring.profiles.active} . ${file-extension}
- order-service.yaml:${prefix} . ${file-extension}
- order-service:${prefix}
@RestController
@RequestMapping("/config")
@RefreshScope
@Slf4j
public class NacosConfigController {
@Value("${test.value}")
private String value;
@GetMapping("/getValue")
public void getValue() {
log.info("getValue:{}", value);
}
}
访问 URL:http://127.0.0.1:8000/config/getValue
删除 order-service-local.yaml,再次访问 URL。
删除 order-service.yaml,再次访问 URL。
结论:配置文件优先级 order-service-loval.yaml > order-service.yaml > order-service
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online