← 返回场景决策

🔵 Nacos 注册中心与配置中心实战

结果导向 · 服务发现 / 配置管理 / 多环境 / 动态刷新 / AP-CP 切换

Nacos 服务发现 配置中心 Namespace 动态刷新 AP/CP 灰度发布

① 直接给结论

Nacos 是什么(一句话):阿里开源的注册中心 + 配置中心二合一,Spring Cloud Alibaba 生态核心组件。一个 Nacos 实例同时搞定服务注册发现和配置管理,比 ZK + Apollo 的组合方案省一半运维。

什么场景该用 Nacos:

场景Nacos 在里面干什么不用会怎样
微服务注册发现服务提供者注册,消费者拉取地址列表,自动感知上下线硬编码 IP 地址,扩缩容要改代码
配置中心配置集中管理,改配置秒级推送到所有实例,不用重启配置散在各机器,改配置要重启所有实例
多环境管理Namespace 隔离 dev/test/prod,一套 Nacos 管所有环境每套环境搭一套配置中心
灰度发布配置按 IP/集群灰度推送,部分实例先生效全量改配置,出问题全挂
服务健康检查心跳检测,不健康的实例自动摘除消费者调到挂掉的实例才发现
一句话选型:Spring Cloud 微服务项目 → Nacos 是默认选择(注册中心+配置中心一站式)。老项目用 ZK/Eureka 的,迁移到 Nacos 是趋势。不需要微服务(单体应用)→ 不需要 Nacos。K8s 生态 → 用 K8s 自带的 Service + ConfigMap,Nacos 可有可无。
Nacos 最大的优势:一个组件搞定两件事。以前要 ZK(注册中心)+ Apollo(配置中心)两个组件,现在 Nacos 一个就够了。运维省一半,配置不用到处找。这是它干掉 ZK+Eureka+Apollo 组合的核心原因。

② Nacos 是什么 + 能力全景

定位:Nacos = Naming and Configuration Service。它的核心是两个服务:服务发现(服务注册、健康检查、地址推送)和配置管理(配置存储、版本管理、动态推送)。两个服务共享同一套存储和集群,部署一个 Nacos 就全有了。

关键认知:Nacos 两种模式可切换
AP 模式(默认):最终一致,服务注册不保证强一致,但可用性高。类似 Eureka。适合大部分场景。
CP 模式:强一致,服务注册保证所有节点数据一致,但可用性略低。类似 ZK。适合需要强一致的场景。
AP 和 CP 的选择:服务发现用 AP(可用性优先),配置管理用 CP(一致性优先)。Nacos 自动选择,你不用操心。
Nacos 工作模型
Nacos Server
(集群3台)
服务提供者
注册+心跳
Nacos Server 服务消费者
拉取地址+订阅变更
调用提供者
负载均衡
Nacos Server 所有实例
配置订阅+动态推送

核心能力全景(6 大块):

📋
服务注册发现
服务启动注册到 Nacos,消费者拉取地址。提供者下线自动摘除,消费者秒级感知。
⚙️
配置管理
配置存 Nacos,应用启动拉取。改配置秒级推送到所有实例,不用重启。支持版本回滚。
🌐
多环境隔离
Namespace 隔离环境(dev/test/prod),Group 分组业务,Data ID 区分配置文件。一套 Nacos 管所有。
💊
健康检查
两种检查:客户端心跳(临时实例)和服务端探测(永久实例)。不健康自动摘除。
🎨
灰度发布
配置按 IP/集群/标签灰度推送,部分实例先生效。支持配置 Beta 发布。
🔄
AP/CP 切换
服务发现 AP 模式(高可用),配置 CP 模式(强一致)。自动选择,也可手动设置。
PRO TIP Nacos 两种实例类型:①临时实例(默认)——客户端主动发心跳,15 秒不发就摘除,适合微服务(服务挂了自动删)。②永久实例——Nacos 主动探测健康,删了不会自动恢复,适合数据库/缓存等基础设施(即使探测不到也保留记录)。微服务用临时实例,基础设施用永久实例。

③ Nacos vs 其他注册/配置方案

维度NacosEurekaZooKeeperConsulApollo
注册中心✅ 支持✅ 支持⚠️ 能做但重✅ 支持❌ 不支持
配置中心✅ 支持❌ 不支持⚠️ 能做但弱✅ 支持✅ 专精
一致性AP/CP 可选APCPCPCP(配置)
健康检查心跳+探测心跳会话探测丰富
配置推送✅ 秒级推送⚠️ Watch一次性✅ 秒级
多环境✅ Namespace❌ 要多套❌ 要多套✅ Datacenter✅ 环境
运维✅ 简单(Docker)✅ 简单⚠️ 麻烦(GC)✅ 简单⚠️ 较复杂
维护状态✅ 活跃(阿里)⚠️ 2.x停更✅ 活跃(Apache)✅ 活跃✅ 活跃(携程)
选它当什么✅ 注册+配置一站式仅注册(老项目)协调(新项目少用)注册+配置(多机房)仅配置(企业级)
实际怎么选:Spring Cloud 新项目 → Nacos(一站式,90% 场景)。只做配置中心且要求企业级 → Apollo(配置管理功能更细)。多数据中心 → Consul。K8s 生态 → K8s 自带 Service+ConfigMap。不要用 Eureka(2.x 停更),不要用 ZK 做注册中心(太重,GC 影响大)。

④ 核心概念(Namespace / Group / Service / Data ID)

Nacos 的组织模型是四层结构:Namespace → Group → Service/Data ID → 实例/配置项。理解这个层级,多环境多业务管理就不会乱。

🔵 Nacos 命名空间 树结构 全局视图 ▾
# Namespace: 隔离环境(最外层) dev (开发环境) ├── DEFAULT_GROUP │ ├── order-service # 服务(注册中心) │ │ ├── 192.168.1.10:8080 (UP) │ │ └── 192.168.1.11:8080 (UP) │ ├── user-service │ └── order-service.yaml # 配置(配置中心) │ └── version=42, lastModified=2026-06-19 ├── PAYMENT_GROUP │ └── pay-servicetest (测试环境) ├── DEFAULT_GROUP │ └── order-service # 和dev同名但不同Namespace,完全隔离prod (生产环境) ⚠️ 最重要 ├── DEFAULT_GROUP │ ├── order-service │ │ ├── 10.0.0.1:8080 (UP) │ │ ├── 10.0.0.2:8080 (UP) │ │ └── 10.0.0.3:8080 (UP) │ └── order-service-prod.yaml # 生产配置 └── PAYMENT_GROUP └── pay-service
🟦 Namespace(环境) → 🟩 Group(业务组) → 🟨 Service/Data ID(服务/配置)
概念作用粒度典型用法
Namespace环境隔离最外层dev / test / prod 三个 Namespace,互不影响
Group业务分组Namespace 内DEFAULT_GROUP(默认) / PAYMENT_GROUP(支付组) / TRADE_GROUP(交易组)
Service / Data ID具体服务/配置Group 内order-service(服务名) / order-service.yaml(配置文件名)
Cluster集群(同机房)Service 内BJ_CLUSTER / SH_CLUSTER,同机房优先调用
Instance实例最内层192.168.1.10:8080 一个具体的服务进程
命名空间的使用原则:不同环境用不同 Namespace(dev/test/prod),不要混在一起;②不同业务用不同 Group,方便管理;③prod Namespace 要加权限,防止误改生产配置。最常见的事故就是开发不小心连了 prod Namespace 改了配置,生产全挂。

⑤ 核心配置实战

5.1 Spring Boot 引入 Nacos

pom.xml
<!-- Nacos 服务发现 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- Nacos 配置中心 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!-- 必须有 bootstrap.yml,配置中心要在这加载 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency>

5.2 bootstrap.yml 配置(注册 + 配置)

bootstrap.yml
📁 resources/
⭐ bootstrap.yml
application.yml
📁 java/
OrderApplication.java
spring: application: name: order-service # 服务名(也是配置的Data ID前缀) cloud: nacos: discovery: # 服务注册 server-addr: 10.0.0.100:8848 # Nacos地址 namespace: prod-ns-id # 生产Namespace的ID(不是名字!) group: DEFAULT_GROUP cluster-name: BJ_CLUSTER # 北京集群 config: # 配置中心 server-addr: 10.0.0.100:8848 namespace: prod-ns-id group: DEFAULT_GROUP file-extension: yaml # 配置文件后缀 refresh-enabled: true # 开启动态刷新 # 拉取的配置: order-service.yaml (服务名+后缀) server: port: 8080
bootstrap.yml vs application.yml 的坑:Nacos 配置中心必须在 bootstrap.yml 里配(不是 application.yml),因为 bootstrap 阶段先于 application 加载。如果配在 application.yml 里,Nacos 配置还没拉下来,@Value 就读不到。这是新手最常见的坑——配了 Nacos 配置中心但不生效,90% 是配错文件了。

5.3 动态刷新配置(@RefreshScope)

OrderConfig.java
@RefreshScope // ← 关键!配置变更后自动重新注入 @Component @ConfigurationProperties(prefix = "order") public class OrderConfig { private Integer timeout; // order.timeout private Integer retry; // order.retry private Boolean enableLog; // order.enable-log // getter/setter 省略 } // 或者用 @Value(也要加 @RefreshScope) @RefreshScope @Service public class OrderService { @Value("${order.timeout:30}") private Integer timeout; public void createOrder() { // 在 Nacos 改了 order.timeout,这里自动变成新值,不用重启 log.info("超时时间: {}", timeout); } }
PRO TIP @RefreshScope 的原理:Nacos 配置变更 → 推送到客户端 → Spring 销毁旧 Bean → 下次调用时创建新 Bean(用新配置注入)。不是立刻生效,是下次调用时生效。所以动态刷新对单例 Bean 有效,但如果配置在启动时一次性读取(比如初始化连接池),改配置不会重建连接池。这种情况要监听 RefreshEvent 手动重建。

⑥ 生产场景(3 个带界面演示)

场景 1:微服务注册发现(上下线自动感知)

背景:订单服务有 5 个实例注册在 Nacos。某个实例 OOM 崩溃,Nacos 15 秒没收到心跳,自动摘除,消费者不再调用它。运维无需手动操作。

📋 服务列表 order-service user-service prod Namespace ▾
健康实例
4
/5 总实例
不健康
1
已自动摘除
消费者
12
已订阅变更
感知延迟
15s
心跳超时
order-service 实例列表:
UP 10.0.0.1:8080 BJ_CLUSTER 心跳 2s前
UP 10.0.0.2:8080 BJ_CLUSTER 心跳 1s前
UP 10.0.0.3:8080 SH_CLUSTER 心跳 3s前
UP 10.0.0.4:8080 SH_CLUSTER 心跳 2s前
DOWN 10.0.0.5:8080 BJ_CLUSTER 心跳 18s前 ⚠️
⚠️ 10.0.0.5 超过15秒未发心跳 → Nacos 标记 DOWN → 推送变更通知给12个消费者 → 消费者摘除该地址
Nacos vs ZK 注册中心的关键差异:Nacos 用客户端主动心跳(5 秒一次,15 秒超时),ZK 用服务端会话(40 秒超时)。Nacos 心跳更细粒度,GC 假死时心跳会恢复,不会误判;ZK 会话超时是硬性的,GC 停顿就摘除。这就是 Nacos AP 模式更适合微服务的原因。

场景 2:配置中心动态调参(不重启改超时时间)

背景:生产环境订单接口超时时间配的 30 秒,某次下游服务慢导致大量请求堆积。需要在 Nacos 改成 10 秒,让请求快速失败,不重启应用

⚙️ 配置管理 order-service.yaml 版本历史 prod ▾
配置版本
v42
最新
已推送
5/5
全部实例
刷新成功
5/5
@RefreshScope
推送延迟
2s
秒级生效
配置内容(order-service.yaml):
order.timeout 10 ← 改了(原30) v42
order.retry 3 v42
order.enable-log true v42
order.max-connections 200 v42
推送日志:
[02:30:01] 配置变更: order.timeout 30 → 10
[02:30:01] 推送到 10.0.0.1:8080 ✓
[02:30:01] 推送到 10.0.0.2:8080 ✓
[02:30:02] 推送到 10.0.0.3:8080 ✓
[02:30:02] 推送到 10.0.0.4:8080 ✓
[02:30:02] 推送到 10.0.0.5:8080 ✓
[02:30:03] 全部 5 实例 @RefreshScope 刷新完成
动态刷新的效果:改配置 → Nacos 推送 → 5 个实例 2 秒内全部生效 → 超时时间从 30s 变成 10s → 堆积请求快速失败释放线程 → 系统恢复。全程不用重启,不用发版。如果用传统配置文件,要改 5 台机器的配置文件 + 重启 5 个应用,至少 10 分钟。

场景 3:多环境配置管理(一套 Nacos 管 dev/test/prod)

背景:3 套环境(dev/test/prod),配置各不同。用 Nacos 的 Namespace 隔离,一套 Nacos 实例管理所有环境配置,不用搭 3 套配置中心。

🌐 多环境管理 Namespace 视图 全局 ▾
dev (开发环境) ├── order-service.yaml │ └── timeout: 60, retry: 1, log-level: DEBUG └── 数据库: 192.168.1.100 (开发库) test (测试环境) ├── order-service.yaml │ └── timeout: 30, retry: 2, log-level: INFO └── 数据库: 192.168.2.100 (测试库) prod (生产环境) 🔒 需要权限 ├── order-service.yaml │ └── timeout: 10, retry: 3, log-level: WARN └── 数据库: 10.0.0.100 (生产库)
环境配置对比:
dev timeout=60, retry=1, DEBUG DB: 192.168.1.100
test timeout=30, retry=2, INFO DB: 192.168.2.100
prod timeout=10, retry=3, WARN DB: 10.0.0.100
✓ 一套 Nacos 管理三套环境,Namespace 隔离互不影响。切换环境只需改 bootstrap.yml 的 namespace 参数。
PRO TIP 多环境管理的最佳实践:①dev/test/prod 用不同 Namespace;②prod Namespace 必须配权限(Nacos 支持账号密码+RBAC),只有运维能改;③配置里不要硬编码环境信息(IP/域名),用 ${ENV:default} 占位符,不同环境配不同值;④每次改 prod 配置先备份版本号(Nacos 自动存版本,可一键回滚)。

⑦ 坑与事故(4 个真实翻车)

事故 1:配在 application.yml 而不是 bootstrap.yml,配置中心不生效

现象:引了 nacos-config 依赖,Nacos 上也配了 order-service.yaml,但应用启动后 @Value 读到的还是默认值,配置没生效。

原因:配在了 application.yml 里。Nacos 配置中心必须在 bootstrap.yml 里配——bootstrap 阶段先于 application 加载,配置中心要先连上才能拉配置。配在 application.yml 里,Spring 加载到 Nacos 配置时,@Value 注入阶段已经过了。

解法:①所有 Nacos 配置中心相关配置放 bootstrap.yml;②Spring Cloud 2020+ 要额外引 spring-cloud-starter-bootstrap 依赖(默认不再加载 bootstrap)。

事故 2:连错 Namespace,开发配置推到生产

现象:开发同学本地调试,bootstrap.yml 的 namespace 填成了 prod 的 ID。本地改配置推送到 prod Namespace,5 个生产实例全部刷新成开发配置(数据库指向了开发库),生产全线故障。

原因:①prod Namespace 没配权限,开发能直接改;②本地配置和线上配置混在一个项目里;③没有配置变更审核机制。

解法:①prod Namespace 必须配权限,只有运维和特定账号能改;②本地开发用 dev Namespace,namespace ID 用环境变量注入而不是硬编码:namespace: ${NACOS_NS:dev-ns-id};③prod 配置变更开启审核(Nacos 企业版支持)。

事故 3:@RefreshScope 配置生效了但连接池没重建

现象:在 Nacos 改了数据库连接池配置(max-size: 50 → 100),@RefreshScope 的 Bean 确实刷新了,但监控显示连接池还是 50。改了等于没改。

原因:HikariCP 连接池在启动时根据配置初始化,@RefreshScope 只是重建了配置 Bean,不会自动重建连接池。连接池对象在 JVM 里还是旧的,配置改了它不知道。

解法:①监听 RefreshEvent 事件,手动销毁旧连接池重建;②连接池类配置不要放 Nacos 动态刷新,改了要重启;③只把"运行时可调"的参数(超时/重试/开关)放 Nacos,"启动时初始化"的参数(连接池/线程池大小)放本地配置文件。

事故 4:Nacos 集群宕机,服务发现瘫痪

现象:Nacos 3 台集群全部宕机(机房断电),所有微服务无法注册/发现,新实例起不来,消费者拉不到地址,全线调用失败。

原因:Nacos 客户端有本地缓存(failover),但默认不开启。Nacos 挂了,客户端没有地址列表可用。

解法:①开启客户端本地缓存:spring.cloud.nacos.discovery.cache-dir=./nacos/cache,Nacos 挂了用缓存的地址列表顶一阵;②Nacos 集群跨机房部署(3 台分 2 机房),单机房挂了还有另一机房;③Nacos 集群配MySQL 持久化,重启后数据不丢;④监控 Nacos 健康,挂了立刻告警。Nacos 是单点风险,必须高可用部署。

⑧ FAQ(5 个高频问题)

Nacos 和 ZooKeeper 该用哪个做注册中心?

新项目选 Nacos。理由:

功能全:Nacos 注册+配置一站式,ZK 只能做注册(配置太弱)。

AP 模式更适合微服务:Nacos 心跳机制对 GC 假死更宽容,ZK 会话超时会误判下线。

运维简单:Nacos 单二进制+Docker 友好,ZK 是 Java 进程有 GC 问题。

生态:Spring Cloud Alibaba 原生支持 Nacos,ZK 要额外配置。

ZK 做注册中心的场景:Dubbo 老项目(ZK 是 Dubbo 默认)、Kafka 元数据存储(Kafka 内置依赖)。新项目别用 ZK 做注册中心。

Nacos 的 AP 和 CP 模式什么时候切换?

Nacos 两种模式自动选择,你一般不用管:

AP 模式(默认,临时实例):服务注册用 AP。客户端主动心跳,Nacos 节点间最终一致。可用性高,适合微服务。90% 场景用这个。

CP 模式(永久实例):永久实例注册用 CP。Nacos 主动探测,节点间强一致。适合数据库/缓存等基础设施。

手动切换:spring.cloud.nacos.discovery.ephemeral: false(改为永久实例,走 CP)。微服务别改,用默认 AP 就行。

配置改了但不生效,怎么排查?

排查清单(按优先级):

配在 bootstrap.yml 了吗?(不是 application.yml)——90% 是这个问题。

加了 @RefreshScope 吗?——没加注解的 Bean 不会刷新。

Data ID 对吗?——默认是 ${spring.application.name}.${file-extension},比如 order-service.yaml。

Namespace 和 Group 对吗?——Namespace 用的是 ID 不是名字,容易填错。

配置是启动时初始化的吗?——连接池/线程池类配置改了不会自动重建,要重启。

看 Nacos 控制台推送日志——确认推送成功没。

Nacos 集群怎么部署?最少几台?

最少 3 台(和 ZK 一样要奇数台,过半写成功)。

部署要点:

• 3 台 Nacos Server,跨机房部署(2+1 或 1+1+1)。

• 共用一个 MySQL(主从),存配置数据(服务注册数据在内存)。

• 前面挂 Nginx/LB,客户端连 LB 地址。

• 每台配 cluster.conf 列出所有节点 IP。

生产推荐 3 台起步,大规模(1000+ 服务)用 5-7 台。不要单机部署生产——Nacos 挂了整个微服务体系瘫痪。

Nacos 和 Apollo 配置中心怎么选?

两个都能做配置中心,区别:

Nacos:注册+配置一站式,配置功能够用。适合 Spring Cloud Alibaba 生态。

Apollo:纯配置中心,功能更专业(灰度发布更细、权限管理更强、多语言客户端全)。

选型建议:Spring Cloud 项目 → Nacos(省一个组件)。对配置管理有极致要求(大型企业、多团队、细粒度权限)→ Apollo。90% 团队 Nacos 配置功能够用了,没必要上 Apollo。

✅ Nacos 三句话速记

1. 定位:注册中心+配置中心一站式,Spring Cloud Alibaba 核心。一个组件干 ZK+Apollo 两个的活。

2. 组织模型:Namespace(环境) → Group(业务) → Service/Data ID(服务/配置) → Instance。prod Namespace 必须配权限。

3. 配置中心必踩坑:配在 bootstrap.yml 不是 application.yml;@RefreshScope 要加;启动时初始化的配置(连接池)改了要重启;Nacos 集群必须 3 台+跨机房。

相关专题:ZooKeeper 专题 · API与微服务决策 · Redis 专题

全栈资料库 · Nacos 注册中心与配置中心实战