前言
本文基于以下版本环境进行实践:
- SpringBoot:
3.2.5 - SpringCloud:
2023.0.3 - SpringCloud Alibaba:
2023.0.1.0 - Nacos:
2.2.3
概述
Nacos (Dynamic Naming and Configuration Service) 是阿里巴巴开源的动态服务发现、配置管理和服务管理平台。在 Spring Cloud 体系中,它主要承担两大职责:服务注册与发现以及动态配置管理。
启动与基础配置
下载 Nacos 后,双击 startup.cmd 即可启动,默认端口为 8848。首次运行建议修改 startup.cmd 中的模式,将 set MODE="cluster" 改为 set MODE="standalone",以便单机调试。
服务注册与发现
微服务架构中,服务提供者(Provider)启动时会将自身网络地址(IP + Port)及服务名称注册到 Nacos;服务消费者(Consumer)则通过查询 Nacos 获取可用实例列表,并根据负载均衡策略调用。Nacos 服务器负责维护这些实例的健康状态。
集成步骤
在模块中引入依赖:
<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 即可看到注册成功的实例。
远程调用优化
RestTemplate 的痛点
传统的同步 HTTP 客户端 RestTemplate 常用于服务间通信。如果直接在代码中硬编码 IP 地址(如 http://127.0.0.1:9000/product/getProductById),一旦服务提供者 IP 变更或环境切换,代码就需要修改,维护成本极高。
结合 Nacos 实现动态调用
借助 Nacos 的服务发现能力,调用方只需知道服务名,Nacos 会自动解析为具体 IP。我们需要引入 spring-cloud-loadbalancer 依赖,并为 RestTemplate 添加 @LoadBalanced 注解。
@Configuration
public class BeanConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
此时 URL 中的 IP 可替换为服务名:
String url = "http://product-service/product/getProductById?id=" + orderInfo.getProductId();
ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
负载均衡策略
Nacos 本身不直接提供负载均衡算法,而是配合客户端负载均衡器(如 Spring Cloud LoadBalancer)使用。默认策略(轮询、随机)可能忽略 Nacos 实例配置的权重。
若要让 Nacos 权重生效,需在消费者端开启 Nacos 负载均衡支持:
spring:
cloud:
loadbalancer:
nacos:
enabled: true
在 Nacos 控制台编辑实例时,可以设置权重值,高权重实例将获得更多流量。
集群与环境隔离
同集群优先访问
为了减少跨机房调用的延迟,可以将服务部署在不同区域(如北京、上海)。通过配置 cluster-name,消费者会优先调用同集群的实例。
spring:
cloud:
nacos:
discovery:
cluster-name: cluster-beijing
命名空间隔离
多环境(开发、测试、生产)之间需要严格隔离。Nacos 通过 Namespace(命名空间)实现这一目标。不同 Namespace 下的服务互不可见。
创建命名空间后,在配置文件中指定 namespace ID:
spring:
cloud:
nacos:
discovery:
namespace: 0bec5adc-2787-44b0-b826-e4bb48746c4e
健康检查机制
Nacos 确保调用指向健康实例,主要有两种模式:
- 客户端主动上报:临时实例默认采用此模式。客户端定时心跳上报,超时未收到则标记不健康或删除。
- 服务器端反向探测:持久实例采用此模式。Nacos 主动探测,失败后标记不健康但不立即删除。
若需将服务注册为非临时实例,配置如下:
spring:
cloud:
nacos:
discovery:
ephemeral: false
注意:实例类型确定后不易更改,若需修改可能需要清理 Nacos 的 Raft 元数据目录并重启。
配置中心实战
传统配置文件存在修改需重启、多环境管理困难等痛点。Nacos 配置中心支持集中管理与实时生效。
Bootstrap 上下文问题
从 Spring Cloud 2020.0.0 开始,默认禁用了 bootstrap 上下文,导致 bootstrap.yml 无法加载。必须显式引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
配置文件优先级
应用启动时会按特定规则构建 Data ID 读取配置,优先级顺序如下:
${prefix} - ${spring.profiles.active}.${file-extension}(例如:order-service-local.yaml)${prefix}.${file-extension}(例如:order-service.yaml)${prefix}(例如:order-service)
这意味着局部环境的配置优先级最高。配合 @RefreshScope 注解,配置变更后可自动刷新 Bean,无需重启服务。
@RestController
@RequestMapping("/config")
@RefreshScope
public class NacosConfigController {
@Value("${test.value}")
private String value;
@GetMapping("/getValue")
public void getValue() {
log.info("getValue:{}", value);
}
}
通过上述配置,我们实现了配置的热更新与多环境隔离,显著提升了微服务运维的灵活性。


