跳转到主要内容

数据库/协同工具类型

Nacos 指南

Nacos 是什么、何时才需要、核心机制(注册中心 + 配置中心 / dataId+group+namespace / Distro+Raft / 内置控制台)、基础实操(Docker 起服务、控制台玩配置和服务发现)、常见问题排查(实例残留、配置不生效)、难点(一致性 vs 可用性、Etcd vs Nacos vs Zookeeper、配置热更新)与生产要点。

  • Nacos
  • 微服务

这是 Nacos 的完整文档:先讲清它是什么、什么时候才需要,再带你用 Docker 跑起来、在控制台玩通配置中心和服务发现,最后是深度参考(核心机制、常见问题、生产要点)。在 Nest 应用里用 Nacos 做配置/服务发现见 Nest 课程第二十二章

一、基础入门(从零开始)

这一节先讲清 Nacos 解决什么问题,再带你跑起来在控制台点一遍;Nest 课程那篇讲的是在应用里用 Nacos SDK——两篇不重复。

1. 先搞懂:Nacos 是什么、什么时候才需要它

拆成微服务后冒出两个麻烦(和 Etcd 那篇一样):

  • 配置散落、改了要重启一堆实例 → 需要配置中心
  • 服务实例 IP 动态变、写死调不通 → 需要注册中心(服务发现)

Nacos(阿里开源)把这俩合在一起做成一个开箱即用的产品,还自带 Web 控制台——这是它和 Etcd(底层 KV,要自己搭)最大的区别:

EtcdNacos
形态底层 KV 存储注册 + 配置 一体的产品
控制台没有,要自己搭内置 Web,点点鼠标就用
上手要自己写配置/发现逻辑开箱即用,API 友好
生态k8s 原生Java / Spring Cloud

Nacos 的两块功能:

  • 配置中心:一条配置用 dataId + group + 命名空间(namespace) 三段定位(如 dataId=app.yaml)。应用启动拉一次,之后订阅变更;你在控制台改了,所有订阅实例实时收到
  • 注册中心(服务发现):服务实例启动时注册自己(自动发心跳保活),调用方查「某服务现在有哪些存活实例」做负载均衡。

核心概念:

  • dataId / group / namespace:定位一条配置的三段(配置的「全限定名」)。
  • 注册 / 心跳:实例登记 + 定时续命,挂了自动摘除。
  • 订阅(subscribe):监听配置或服务列表变更,一变就推。

一句话:拆了微服务、想要「带控制台、开箱即用」的配置 + 服务发现,尤其 Java/Spring Cloud 技术栈,用 Nacos

2. 用 Docker 起一个 Nacos(standalone)

docker run -d --name nacos \
  -p 8848:8848 -p 9848:9848 \
  -e MODE=standalone \
  nacos/nacos-server:v2.2.3
  • MODE=standalone:单机模式(生产用集群)。
  • 8848:HTTP / 控制台端口;9848:2.x 客户端 gRPC 端口(两个都要开)。
  • 浏览器打开 http://localhost:8848/nacos ,默认账号 nacos / nacos
  • docker logs nacos 看到 Nacos started successfully 就好了。

3. 控制台玩一遍:配置中心 + 服务发现

配置中心(点点鼠标就行):

  1. 左侧「配置管理 → 配置列表」→ 右上角 + 新建配置。
  2. Data ID(如 app.yaml)、Group(默认 DEFAULT_GROUP)、配置内容(如 theme: dark)→ 发布。
  3. 应用订阅这个 dataId 后,你在这把 theme 改成 light 再发布 → 应用实时收到新值,不用重启。

服务发现

  1. 启动一个服务、用 SDK 注册到 Nacos(实例出现在「服务管理 → 服务列表」)。
  2. 列表里能看到实例的 IP、端口、健康状态(绿点 = 健康)。
  3. 把实例停掉 → 列表里很快变红/消失;调用方查 order-service 拿到的实例列表也会同步少一个。

→ 这就是配置中心(改了实时推)和服务发现(实例上下线实时同步)的本质。

4. 核心概念

  • 三段定位配置dataId(配置名,如 app.yaml)+ group(分组,默认 DEFAULT_GROUP)+ namespace(命名空间,做环境隔离,如 dev/prod)。三者一起唯一定位一条配置。
  • 注册 / 心跳:实例启动调 registerInstance 注册、每 5 秒发一次心跳;下线调 deregisterInstance。心跳超时 Nacos 自动摘除。
  • 订阅(subscribe):调用方 subscribe('order-service', cb),实例列表一变就触发回调。
  • API:注册 registerInstance、注销 deregisterInstance、查实例 getAllInstances('order-service')

5. 基本使用规则

  • 没拆微服务别上.env 够用,引入 Nacos 是过度设计。
  • 用 namespace 隔离环境:dev / test / prod 各一个 namespace,配置互不干扰。
  • 订阅要配全量兜底:断连重连后先全量拉一次再订阅,别只靠推送(会漏变更)。
  • 实例下线主动 deregister + 靠心跳兜底,调用方再做重试,别盲信注册中心。
  • 生产集群 ≥3 节点,单节点别上生产。

6. 核心词汇速记

术语一句话
配置中心配置集中存、改了实时推,不用改代码重启
注册中心 / 服务发现服务实例动态上下线,调用方实时查存活实例
dataId / group / namespace定位一条配置的三段
注册 / 心跳实例登记 + 定时续命,挂了自动摘除
订阅(subscribe)监听配置或服务列表变更,一变就推
namespace(命名空间)做环境隔离,dev / prod 各一套

二、作用与定位

Nacos 是阿里开源的注册中心 + 配置中心 一体化产品,最大卖点是自带 Web 控制台、开箱即用,在 Java / Spring Cloud 生态里几乎是标配。和 Etcd(底层 KV、k8s 原生、要自己搭逻辑)互补:Nacos 重「好上手、有界面」,Etcd 重「强一致、轻量」。

用途Nacos 怎么做
配置中心dataId+group+namespace 存配置,订阅推送
服务发现实例注册+心跳,调用方查实例列表

一句话:Java/微服务、想要「带控制台、开箱即用」的配置 + 服务发现,用 Nacos

三、何时该用 / 何时用别的

场景选择
单体 / 少量服务@nestjs/config + .env,不上配置中心
多服务、配置要集中推送Nacos(或 Etcd/Apollo/Consul)
微服务、节点动态增删Nacos(或 Etcd/Consul)
已上 k8s配置用 ConfigMap,发现用 Service/k8s DNS
要强一致选主/协调Etcd(Nacos 配置是 CP,但选主生态不如 Etcd)

别为了用而用:3 个服务以内,.env + 负载均衡器就够了。

四、核心机制速览

  • 注册 + 配置两套 API,带 Web 控制台(这是它比 Etcd 友好的地方)。
  • 服务发现registerInstance / deregisterInstance / getAllInstances,客户端自动心跳。
  • 配置:以 dataId + group + namespace 定位,subscribe 监听变更。
  • 一致性(关键):注册信息用 Distro(AP,可用性优先),配置用 Raft(CP)AP 意味着短暂可能拿到旧实例列表——靠重试兜底。
  • 都靠订阅推变更、靠心跳摘挂掉的实例。

服务注册与发现的完整时序(注册 → 心跳 → 订阅 → 下线摘除):

sequenceDiagram autonumber participant P as 服务提供者 participant N as Nacos participant C as 服务消费者 P->>N: 启动时注册实例 loop 每5秒心跳 P->>N: keep-alive end C->>N: 订阅服务实例列表 N-->>C: 返回当前存活实例 Note over P: 实例下线 心跳停止 N-->>C: 推送变更 摘除该实例

五、常见问题与排查

1. 服务实例「残留」(下线了还在列表里)

原因:实例没正常注销(强杀、网络分区),心跳还没超时。

解决

  • 靠心跳超时自动摘除——TTL 别设太长。
  • 健康检查:调用方拿到实例列表后,再做主动健康检查 / 重试,别盲信注册中心。
  • 实例正常退出时主动 deregisterInstance

2. 客户端配置缓存不更新

原因:配置在本地缓存了一份,但没订阅变更或订阅断了。

解决:启动时拉一次 + 订阅变更;变更回调里更新本地缓存 + 重新生效(如重建连接池)。注意配置热更新不是所有配置都支持(连接池大小改了要重建池)。

3. 订阅 / 推送丢失变更

原因:网络抖动断连,断连期间的变更没收到。

解决:客户端重连后做一次全量拉取 + 重新订阅。别只依赖推送、不做全量兜底。

六、难点与解决方案

1. 一致性 vs 可用性(CAP)

系统取向含义
Etcd / ZookeeperCP分区时宁可拒服务也要一致——适合配置、选主(不能错)
Nacos(注册)/ EurekaAP分区时各 partition 都能用——适合服务发现(宁可给旧实例,重试就行)

Nacos 的聪明之处:注册用 AP(服务发现要的是可用,宁可短暂给旧实例+重试,也不能让注册中心挂了拖垮调用链)、配置用 CP(配置不能错)。服务发现选 AP;选主/配置选 CP。

2. Etcd vs Nacos vs Zookeeper 怎么选

维度EtcdNacosZookeeper
一致性CP(Raft)注册 AP / 配置 CPCP(ZAB)
控制台内置 Web
易用性KV 原始,要自己封装API 友好、生态(Spring Cloud)重、复杂
适合k8s、需要 CP 原语Java/微服务、要可视化老系统(Dubbo/Kafka)

新项目:上 k8s → Etcd;Java 微服务 → Nacos;要选主/分布式协调 → Etcd 或 Zookeeper。

3. 配置热更新

配置改了怎么让运行中的应用生效?

  • 订阅模式:监听变更,回调里更新内存配置。
  • 注意「不能热更」的:数据库连接池大小、端口等改了要重启或重建资源——这类变更要配套重建逻辑,不是改个值就行。

配置中心热更新的完整时序(控制台改配置 → 推送 → 回调刷新本地):

sequenceDiagram autonumber participant U as 运维 participant N as Nacos控制台 participant A as 应用客户端 A->>N: 启动时拉取配置并订阅 N-->>A: 返回当前配置 U->>N: 修改配置并发布 N-->>A: 推送配置变更 Note over A: 回调里刷新本地配置 即时生效

七、生产环境要点

  • 集群 ≥3 节点,单节点别上生产。
  • 客户端要重连 + 全量兜底,别只靠推送。
  • 心跳 / TTL别设太长(实例挂了要尽快摘除),也别太短(网络抖动误判)。
  • 调用方做重试 + 健康检查,别盲信注册中心的实例列表。
  • 用 namespace 隔离环境,别把 dev 和 prod 配置混在一起。
  • 监控:集群节点健康、leader 是否稳定、服务/配置数、推送延迟。

速查:常见问题对照

问题原因解决
实例残留没正常注销心跳自动摘 + 主动 deregister + 健康检查
配置不生效没订阅 / 没热更订阅变更、回调里重建资源
推送漏变更断连重连后全量拉 + 重新订阅
拿到旧实例列表注册是 AP调用方重试 + 健康检查兜底
Nacos 挂了全瘫单点集群 ≥3 + 客户端缓存本地兜底