Spring Cloud Alibaba Nacos 保姆级入门教程 —— 注册中心 & 配置中心全搞定
菜鸟的修仙笔记,一边学一边记,有不对的地方欢迎大佬指正
前言
最近在学 Spring Cloud 微服务体系,今天磕了一下午的 Nacos,从注册中心到配置中心,从服务发现到负载均衡再到配置自动刷新,总算把核心链路捋顺了。趁热打铁写篇博客,狠狠真实一下自己。
先放一张整体架构图,心里有个谱:
┌──────────────────────────────────────────────────────────┐
│ Nacos Server │
│ ┌─────────────────────┐ ┌───────────────────────────┐ │
│ │ 注册中心 │ │ 配置中心 │ │
│ │ (服务注册 & 发现) │ │ (配置管理 & 动态刷新) │ │
│ └──────┬──────────────┘ └────────────┬──────────────┘ │
└─────────┼──────────────────────────────┼─────────────────┘
│ │
┌─────▼─────┐ ┌─────▼─────┐
│ order服务 │ │ order服务 │
│ 注册到Nacos│ │ 拉取配置 │
│ 发现user服务│ │ 监听变化 │
└─────┬─────┘ └───────────┘
│
┌─────▼─────┐
│ LoadBal │
│ ancer │
│ 负载均衡 │
└───────────┘
一、注册中心
1.1 什么是注册中心?
微服务架构下,服务实例的网络地址是动态变化的(扩缩容、故障转移),不可能把 IP 写死在代码里。注册中心就是所有服务的"通讯录":
-
服务启动时向注册中心注册自己的地址
-
服务调用时从注册中心发现目标服务的地址列表
1.2 引入 Nacos 注册中心
第一步:加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
第二步:配地址
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848 # Nacos 服务地址
application:
name: order-service # 服务名,注册时以此作为标识
第三步:启动类加注解
@SpringBootApplication
@EnableDiscoveryClient // 开启服务发现
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
启动后去 Nacos 控制台 localhost:8848/nacos → 服务管理 → 服务列表,就能看到 order-service 了。
二、服务调用 & 负载均衡
注册只是第一步,真正关键的是怎么调用。
2.1 RestTemplate + @LoadBalanced
最经典的方式,用 RestTemplate 发起 HTTP 调用,加 @LoadBalanced 注解开启负载均衡:
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced // 核心:让 RestTemplate 拥有负载均衡能力
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
调用时直接用服务名代替 IP:端口:
@Service
public class OrderService {
@Autowired
private RestTemplate restTemplate;
public User getUserById(Long id) {
// 注意:URL 里写的是服务名,不是 IP!
String url = "http://user-service/user/" + id;
return restTemplate.getForObject(url, User.class);
}
}
@LoadBalanced 做了什么事?
restTemplate.getForObject("http://user-service/user/1", User.class)
│
▼
┌─────────────────┐
│ 拦截器拦截请求 │ ← LoadBalancerInterceptor
│ 从 URL 中提取服务名│
└────────┬────────┘
│
▼
┌─────────────────┐
│ 从 Nacos 获取 │ ← NacosServerList
│ user-service 的 │
│ 所有实例列表 │
│ [192.168.1.1:8081│
│ 192.168.1.2:8082│
│ 192.168.1.3:8083]│
└────────┬────────┘
│
▼
┌─────────────────┐
│ 负载均衡算法选择 │
│ 一个实例 │
│ → 192.168.1.2:8082│
└────────┬────────┘
│
▼
┌─────────────────┐
│ 替换 URL 为真实地址│
│ http://192.168.1.2│
│ :8082/user/1 │
└─────────────────┘
2.2 LoadBalancerClient
除了用 @LoadBalanced 注解,也可以直接注入 LoadBalancerClient 手动选择实例:
@Service
public class OrderService {
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
public User getUserById(Long id) {
// 手动选择服务实例
ServiceInstance instance = loadBalancerClient.choose("user-service");
// 拿到真实的 host:port
String url = String.format("http://%s:%s/user/%s",
instance.getHost(), instance.getPort(), id);
return restTemplate.getForObject(url, User.class);
}
}
两种方式对比:
| 方式 | 优点 | 缺点 |
|---|---|---|
@LoadBalanced |
代码简洁,注解驱动 | 不够灵活,无法自定义选择逻辑 |
LoadBalancerClient |
灵活,可以拿到实例元数据 | 代码量稍多,需手动拼接 URL |
三、配置中心
注册中心搞定了"服务在哪"的问题,配置中心解决的是"配置怎么管"的问题。
3.1 为什么需要配置中心?
痛点场景:
-
10 个微服务,每个都有
application.yml,改个数据库地址要改 10 个文件 -
改了配置文件要重启服务才能生效
-
敏感信息(密码)散落在各个配置文件里,不安全
配置中心就是把所有配置统一管理、动态刷新的地方。
3.2 接入 Nacos 配置中心
第一步:加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
第二步:配 Nacos 地址
spring:
application:
name: order-service
cloud:
nacos:
config:
server-addr: localhost:8848
第三步:在 Nacos 控制台创建配置
进入 Nacos → 配置管理 → 配置列表 → 创建配置:
| 字段 | 值 | 说明 |
|---|---|---|
| Data ID | order-service.yaml |
默认规则:${spring.application.name}.${file-extension} |
| Group | DEFAULT_GROUP |
默认分组 |
| 配置内容 | 见下方 |
# Nacos 控制台里的配置内容
user:
name: 张三
age: 18
3.3 使用 spring.config.import 导入配置
Spring Boot 2.4+ 推荐用 spring.config.import 导入 Nacos 配置:
# application.yml
spring:
config:
import:
- nacos:order-service.yaml # 导入 Nacos 配置
- nacos:common.yaml # 可以导入多个
cloud:
nacos:
config:
server-addr: localhost:8848
引入多个 data-id 的场景:
order-service.yaml ← 订单服务独有配置
common.yaml ← 公共配置(各服务共享)
order-service-dev.yaml ← 开发环境配置
四、配置取值 & 自动刷新
4.1 @Value + @RefreshScope
@RestController
@RefreshScope // 关键:标记这个 Bean 的 @Value 字段需要动态刷新
public class TestController {
@Value("${user.name}")
private String userName;
@Value("${user.age}")
private Integer age;
@GetMapping("/user-info")
public String getUserInfo() {
return "姓名:" + userName + ",年龄:" + age;
}
}
验证自动刷新:
-
访问
/user-info→姓名:张三,年龄:18 -
去 Nacos 控制台把
user.age改成20,发布 -
再次访问
/user-info→姓名:张三,年龄:20✅ 不用重启!
原理简述:
Nacos 配置变更
│
▼
Nacos Client 收到通知
│
▼
Spring Cloud 刷新 Context
│
▼
@RefreshScope 标注的 Bean 被重建
│
▼
@Value 重新从 Environment 取值 → 新值生效
4.2 @ConfigurationProperties 批量绑定
当配置项很多时,一个个 @Value 太累了,用 @ConfigurationProperties 批量绑定:
Nacos 配置:
user:
name: 张三
age: 18
addr:
province: 广东
city: 深圳
配置类:
@Component
@ConfigurationProperties(prefix = "user") // 绑定 user 开头的所有配置
@RefreshScope // 同样支持自动刷新!
@Data
public class UserProperties {
private String name;
private Integer age;
}
}
使用:
@RestController
public class TestController {
@Autowired
private UserProperties userProperties;
@GetMapping("/user-info")
public String getUserInfo() {
return userProperties.getName() + " - "
+ userProperties.getAddr().getProvince();
}
}
@Value vs @ConfigurationProperties 对比:
| 维度 | @Value | @ConfigurationProperties |
|---|---|---|
| 单个属性 | ✅ 方便 | 也能用但杀鸡用牛刀 |
| 批量绑定 | ❌ 要写很多个 | ✅ 一个 prefix 搞定 |
| 嵌套对象 | ❌ 不支持 | ✅ 自动映射 |
| 松散绑定 | ❌ 不支持 | ✅ user-name → userName |
| 数据校验 | ❌ 不支持 | ✅ 可以用 @Validated |
| 自动刷新 | 需要 @RefreshScope |
需要 @RefreshScope |
推荐: 单两个属性用 @Value,多了就用 @ConfigurationProperties。
4.3 NacosConfigManager 监听配置变化
前面两种方式都是被动刷新,如果你想主动感知配置变化并做一些处理(比如重建连接池),可以用 NacosConfigManager 注册监听器:
@Component
public class ConfigListenerDemo {
@Autowired
private NacosConfigManager nacosConfigManager;
@PostConstruct
public void init() {
// 获取 ConfigService
ConfigService configService = nacosConfigManager.getConfigService();
try {
// 添加监听器:dataId, group, 回调
configService.addListener("order-service.yaml", "DEFAULT_GROUP",
new Listener() {
@Override
public Executor getExecutor() {
return Executors.newSingleThreadExecutor();
}
@Override
public void receiveConfigInfo(String configInfo) {
// configInfo 就是最新的配置内容(yaml 原文)
System.out.println("配置变了!新配置:\n" + configInfo);
// 在这里做一些自定义逻辑
// 比如:重建数据库连接池、清空缓存等
onConfigChanged(configInfo);
}
});
} catch (NacosException e) {
e.printStackTrace();
}
}
private void onConfigChanged(String newConfig) {
// 自定义处理逻辑
}
}
五、扩展:配置隔离 & 环境切换
5.1 配置的三级隔离
Nacos 通过三个维度实现配置隔离:
Namespace(命名空间)
└── Group(分组)
└── Data ID(配置集ID)
└── 具体配置内容
5.2 Namespace —— 环境隔离
典型用法:用 namespace 区分开发/测试/生产环境。
spring:
cloud:
nacos:
config:
server-addr: localhost:8848
namespace: dev-env-id-xxxx # 用 namespace 的 ID
不同 namespace 的配置完全隔离,dev 环境看不到 prod 的配置。
5.3 Group —— 微服务分组
同一个 namespace 下,用 group 对不同微服务做逻辑分组:
Group: ORDER_GROUP
├── order-service.yaml
└── order-db.yaml
Group: USER_GROUP
├── user-service.yaml
└── user-db.yaml
spring:
cloud:
nacos:
config:
group: ORDER_GROUP # 指定分组
5.4 Data ID —— 配置集拆分
利用 data-id 把一个大配置文件拆成多个小配置:
order-service.yaml # 主配置
order-service-datasource.yaml # 数据源配置
order-service-cache.yaml # 缓存配置
order-service-mq.yaml # 消息队列配置
这样改造数据源时只改 *-datasource.yaml,不会误触其他配置。
5.5 优先
配置优先级(由低到高):
-
共享配置(shared-configs)
-
扩展配置(extension-configs)
-
应用专属配置(
${spring.application.name}.yaml) -
应用+环境配置(
${spring.application.name}-${profile}.yaml)
优先级高的会覆盖优先级低的同名配置,这就是 "近者优先" 原则。
六、完整 Demo 流程回顾
把今天学的串起来,实现一个完整调用链路:
User 请求 GET /order/1
│
▼
┌─────────────┐ 2. 从 Nacos 注册中心
│ order-service│ ◄─── 发现 user-service 的实例列表
└──────┬──────┘
│ 1. order-service 启动时
│ 从 Nacos 配置中心拉取配置
│ 注册自己到 Nacos
│
│ 3. 使用 @LoadBalanced RestTemplate
│ 或 LoadBalancerClient
│ 负载均衡选择一个 user-service 实例
│
▼
┌─────────────┐
│ user-service │
│ 实例 2 │ ◄─── 4. 实际发起 HTTP 调用
└─────────────┘
│
│ 5. user-service 处理请求
│ 读取的配置如果被修改
│ @RefreshScope 自动刷新
│
▼
返回结果给 order-service → 返回给 User
关键依赖:
<!-- 注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
总结
今天学的内容其实就两条主线:
| 注册中心 | 配置中心 | |
|---|---|---|
| 核心问题 | 服务在哪? | 配置怎么管? |
| 关键注解 | @EnableDiscoveryClient、@LoadBalanced |
@RefreshScope、@ConfigurationProperties |
| 服务调用 | RestTemplate / LoadBalancerClient |
- |
| 负载均衡 | 轮询 → 可自定义 | - |
| 配置刷新 | - | @Value 刷新 / NacosConfigManager 监听 |
| 隔离体系 | namespace → group → serviceName | namespace → group → dataId |
Nacos = 注册中心 + 配置中心
更多推荐

所有评论(0)