系列开篇
在微服务大行其道的今天,Nacos 已成为国内最受欢迎的动态服务发现、配置管理平台之一。但很多程序员只停留在“会用”层面,对它的核心原理一知半解。这个系列将带你系统性拆解 Nacos 的内部机制,从架构设计到一致性协议,再到源码实现,让你彻底看懂 Nacos。

本篇作为开篇,我们先建立一个全局认知:Nacos 整体架构长什么样?为什么它能在一个平台里同时提供注册中心和配置中心两种服务?它到底支持 AP 还是 CP?


一、Nacos 解决了什么问题?

微服务架构有两个最基本的需求:

  1. 服务发现:服务提供者注册上来,消费者能动态发现并调用,且当实例下线或故障时能快速感知。

  2. 配置管理:应用配置集中管理,变更时能实时推送到所有客户端,无需重启。

市面上常见的方案是:用 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(命名空间):用于多环境/多租户隔离,如 devprod。不同命名空间的数据完全不可见。

  • 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 状态机同步。在部署时只需关注两点:

  1. 集群节点数最好是奇数(方便 Raft 选举)。

  2. 配置中心的数据量通常比注册中心小,因此不会对 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 篇:服务注册与发现:心跳、摘除与健康检查》。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐