Nacos第 1 篇: 架构设计:为什么既能做注册中心(AP),又能做配置中心(CP)?
Nacos 是融合“服务发现”与“配置管理”的一体化平台。数据模型采用 Namespace → Group → Service/Config 的分层隔离。服务发现(临时实例)使用自研 Distro 协议,遵循 AP 模型;配置管理使用 Raft 协议,遵循 CP 模型。整体架构由控制台、SDK、服务端、存储层组成,插件化设计支撑扩展。理解了这些,你就抓住了 Nacos 的设计灵魂。从下一篇开始,我
系列开篇
在微服务大行其道的今天,Nacos 已成为国内最受欢迎的动态服务发现、配置管理平台之一。但很多程序员只停留在“会用”层面,对它的核心原理一知半解。这个系列将带你系统性拆解 Nacos 的内部机制,从架构设计到一致性协议,再到源码实现,让你彻底看懂 Nacos。
本篇作为开篇,我们先建立一个全局认知:Nacos 整体架构长什么样?为什么它能在一个平台里同时提供注册中心和配置中心两种服务?它到底支持 AP 还是 CP?
一、Nacos 解决了什么问题?
微服务架构有两个最基本的需求:
-
服务发现:服务提供者注册上来,消费者能动态发现并调用,且当实例下线或故障时能快速感知。
-
配置管理:应用配置集中管理,变更时能实时推送到所有客户端,无需重启。
市面上常见的方案是:用 Eureka / Consul 做服务发现,用 Apollo / Spring Cloud Config 做配置中心。但 Nacos 的设计目标是 “一个平台,双倍能力” ,将两者融合在一起,降低运维复杂度。不仅如此,它还在服务发现场景追求高可用和分区容忍性(AP),在配置管理场景追求强一致性(CP),这种 “AP + CP 混合模式” 正是 Nacos 最独特的地方。
二、Nacos 整体架构:四大模块协同
先看一张简化的架构图(文字描述):
text
┌──────────────────────────────────────────┐ │ Nacos 生态 │ ├──────────┬──────────┬──────────┬─────────┤ │ 控制台 │ SDK │ 服务端 │ 存储层 │ │ Console │ Client │ Server │ Store │ └──────────┴──────────┴──────────┴─────────┘
-
控制台(Console):提供 Web UI,用于服务管理、配置编辑、权限控制等,背后调用服务端 API。
-
SDK(Client):嵌入到业务应用中的 Java/Go/Node.js 等客户端,负责服务注册/发现、配置拉取/监听。
-
服务端(Server):Nacos 的核心,处理注册请求、心跳检测、配置持久化、集群同步等,全部以 HTTP/gRPC 接口暴露。
-
存储层(Store):Nacos 使用嵌入式数据库(Derby)或外部 MySQL 来持久化数据,同时内存中也有缓存以提供高性能。
关键设计:双引擎驱动
服务端内部可以拆分为两大子系统:
-
Naming Service(命名服务):负责服务注册与发现。
-
Config Service(配置服务):负责配置的增删改查与动态推送。
这两个子系统共享同一套集群通信、鉴权、监控等基础能力,但在一致性协议上选择不同的策略,这就是“一个集群,两种一致性”的由来。
三、Nacos 数据模型:命名空间、分组与服务
理解 Nacos 的数据组织方式是驾驭它的基础。
-
Namespace(命名空间):用于多环境/多租户隔离,如
dev、prod。不同命名空间的数据完全不可见。 -
Group(分组):在同一个 Namespace 下对服务或配置进行更细粒度的归类,如
DEFAULT_GROUP。 -
Service(服务名):一个微服务的标识,下面可以有多个实例。
-
Instance(实例):服务提供者的具体节点,包含 IP、端口、权重、健康状态等。实例又分为:
-
临时实例(ephemeral=true):默认类型,通过心跳维持存活,走 AP 协议。
-
持久实例(ephemeral=false):仅在主动注销或健康检查失败时移除,走 CP 协议(实际较少使用)。
-
-
Config(配置):一个配置项,由
Data ID+Group+Namespace唯一确定,内容包括文本、JSON、XML 等。 -
Cluster(集群):实例可以归属到不同虚拟集群(如机房划分),用于就近路由和容灾。
这个模型既灵活又分层,能够支撑从单机到大规模集群的各种场景。
四、AP 与 CP 的抉择:Nacos 如何做到兼得?
这是 Nacos 最精华的设计。我们直接抛出结论:
| 功能模块 | 一致性模型 | 使用协议 | 典型场景 |
|---|---|---|---|
| 服务发现 | AP | Distro 协议 | 临时实例的注册与心跳 |
| 配置管理 | CP | Raft 协议 | 配置的发布、修改、删除 |
| 持久实例 | CP | Raft 协议 | 需要长期存在且不依赖心跳的实例 |
为什么服务发现选择 AP?
在微服务调用链路中,可用性比一致性优先级更高。当网络分区发生时,即使个别节点数据暂时不一致,只要还能返回可用的实例列表,调用就不会中断。牺牲一点强一致性,换取整个系统的持续可用,这是典型的 AP 思想。
Nacos 在服务发现模块实现了自研的 Distro 协议(Distributed 缩写)。它是专门为临时实例设计的最终一致性协议,特点是:
-
每个 Nacos 节点都有全量数据,能够独立响应查询。
-
注册信息通过异步方式复制到其他节点。
-
健康检查由各个节点独立执行,触发数据同步。
-
采用版本号机制解决冲突,最终达到一致。
Distro 保证:当客户端向任意一台 Nacos 注册/查询服务,都能拿到结果,不会因为部分节点故障而阻塞。
为什么配置管理选择 CP?
配置数据直接影响到业务行为,绝不能出现“发布成功后又丢失”或“多版本读取不一致”的问题。比如你修改了数据库连接池大小,如果有的节点读到旧值,有的读到新值,线上就可能出事故。
因此配置中心必须采用 CP 模型,Nacos 选择了工业界成熟的 Raft 协议(具体实现为 JRaft 库)。Raft 通过 Leader 选举、日志复制和提交确认,确保:
-
任何配置变更需要在集群半数以上节点写入成功才返回。
-
在 Leader 宕机时能自动选出新 Leader,保证服务可用。
-
客户端读取配置总是从 Leader 或满足线性一致性的 Follower 读取。
这样,配置发布就有“存必可达,读无脏数据”的强一致性保障。
混合部署如何实现?
在一个 Nacos 集群中,Distro 和 Raft 可以同时运行,互不干扰。服务发现数据通过 Distro 网络层异步同步,配置数据通过 Raft 状态机同步。在部署时只需关注两点:
-
集群节点数最好是奇数(方便 Raft 选举)。
-
配置中心的数据量通常比注册中心小,因此不会对 Distro 产生压力。
后续文章会深入 Distro 和 Raft 的原理,这里你只需要记住:临时实例走 AP,配置和持久实例走 CP。 这就是 Nacos 双模式的核心。
五、插件化设计:让 Nacos 更灵活
Nacos 的另一大亮点是高度插件化,可以方便地替换底层实现而不侵入核心逻辑。常见的扩展点:
-
健康检查插件:支持 HTTP、TCP、MySQL 等检查方式,你也可以自定义。
-
配置存储插件:默认 Derby / MySQL,但通过 SPI 可扩展为其他数据库。
-
集群同步插件:Distro 和 Raft 本身也是可替换的(不过一般不用动)。
-
鉴权插件:支持 LDAP、OIDC 等。
-
跟踪与监控:集成 Prometheus、SkyWalking 等。
这种设计使得 Nacos 能够适应不同的企业环境,同时保持内核稳定。
六、本篇总结与下篇预告
本篇核心要点:
-
Nacos 是融合“服务发现”与“配置管理”的一体化平台。
-
数据模型采用 Namespace → Group → Service/Config 的分层隔离。
-
服务发现(临时实例)使用自研 Distro 协议,遵循 AP 模型;配置管理使用 Raft 协议,遵循 CP 模型。
-
整体架构由控制台、SDK、服务端、存储层组成,插件化设计支撑扩展。
理解了这些,你就抓住了 Nacos 的设计灵魂。从下一篇开始,我们将深入 服务注册与发现 的具体流程:心跳机制如何工作?临时实例和持久实例的实现有什么不同?健康检查背后的细节是什么?敬请期待《第 2 篇:服务注册与发现:心跳、摘除与健康检查》。
更多推荐



所有评论(0)