type
status
date
slug
summary
tags
category
icon
password
1、基础架构
Nacos 是阿里巴巴开源的一款服务发现、配置管理和服务管理平台。Nacos 具备服务注册发现功能,类似于Zookeeper、Consul、Eureka,同时又提供了分布式配置中心的功能,类似于Spring Cloud Config、Apollo。Nacos 主要提供以下四大功能:
- 服务发现与服务健康检查
Nacos使服务更容易注册,并通过DNS或HTTP接口发现其他服务,Nacos还提供服务的实时健康检查,以防止向不健康的主机或服务实例发送请求。
- 动态配置管理
动态配置服务允许您在所有环境中以集中和动态的方式管理所有服务的配置。Nacos消除了在更新配置时重新部署应用程序,这使配置的更改更加高效和灵活。
- 动态DNS服务
Nacos提供基于DNS 协议的服务发现能力,旨在支持异构语言的服务发现,支持将注册在Nacos上的服务以域名的方式暴露端点,让三方应用方便的查阅及发现。
- 服务和元数据管理
Nacos 能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略。
1.1 整体架构

- Provider APP:服务提供者。
- Consumer APP:服务消费者。
- Name Server:通过Virtual IP或者DNS的方式实现Nacos高可用集群的服务路由。
- Nacos Server:Nacos服务提供者。
- OpenAPI:功能访问入口。
- Config Service、Naming Service:Nacos提供的配置服务、名字服务模块。
- Consistency Protocol:一致性协议,用来实现Nacos集群节点的数据同步,使用Raft算法实现。
- Nacos Console:Nacos控制台。

用户层
- OpenAPI:暴露标准Rest风格HTTP接口,简单易用,方便多语言集成
- Console:易用控制台,做服务管理、配置管理等操作
- SDK:多语言 SDK,目前几乎支持所有主流编程语言
- Agent:Sidecar 模式运行,通过标准 DNS 协议与业务解耦
- CLI:命令行对产品进行轻量化管理,像 git 一样好用
业务层
- 服务管理:实现服务 CRUD,域名 CRUD,服务健康状态检查,服务权重管理等功能
- 配置管理:实现配置管 CRUD,版本管理,灰度管理,监听管理,推送轨迹,聚合数据等功能
- 元数据管理:提供元数据 CURD 和打标能力,为实现上层流量和服务灰度非常关键
内核层
- 插件机制:实现三个模块可分可合能力,实现扩展点 SPI 机制,用于扩展自己公司定制
- 事件机制:实现异步化事件通知,SDK 数据变化异步通知等逻辑,是Nacos高性能的关键部分
- 日志模块:管理日志分类,日志级别,日志可移植性(尤其避免冲突),日志格式,异常码+帮助文档
- 回调机制:SDK 通知数据,通过统一的模式回调用户处理。接口和数据结构需要具备可扩展性
- 寻址模式:解决 Server IP 直连,域名访问,Nameserver 寻址、广播等多种寻址模式,需要可扩展
- 推送通道:解决 Server 与存储、Server 间、Server 与 SDK 间高效通信问题
- 容量管理:管理每个租户,分组下的容量,防止存储被写爆,影响服务可用性
- 流量管理:按照租户,分组等多个维度对请求频率,长链接个数,报文大小,请求流控进行控制
- 缓存机制:容灾目录,本地缓存,Server 缓存机制,是 Nacos 高可用的关键
- 启动模式:按照单机模式,配置模式,服务模式,DNS 模式,启动不同的模块
- 一致性协议:解决不同数据,不同一致性要求情况下(包括AP 协议和CP协议)的诉求
- 存储模块:解决数据持久化、非持久化存储,解决数据分片问题
插件
- Nameserver:解决 Namespace 到 ClusterID 的路由问题,解决用户环境与 Nacos 物理环境映射问题
- CMDB:解决元数据存储,与三方 CMDB 系统对接问题,解决应用,人,资源关系
- Metrics:暴露标准 Metrics 数据,方便与三方监控系统打通
- Trace:暴露标准 Trace,方便与 SLA 系统打通,日志白平化,推送轨迹等能力,并且可以和计量计费系统打通
- 接入管理:相当于阿里云开通服务,分配身份、容量、权限过程
- 用户管理:解决用户管理,登录,SSO 等问题
- 权限管理:解决身份识别,访问控制,角色管理等问题
- 审计系统:扩展接口方便与不同公司审计系统打通
- 通知系统:核心数据变更,或者操作,方便通过SMS系统打通,通知到对应人数据变更
1.2 Nacos的服务注册和发现原理
服务注册和发现流程:

流程:
- 注册中心启动:服务容器负责启动,加载,运行服务提供者。
- 服务提供者注册:服务提供者在启动时,向注册中心注册自己提供的服务。Nacos Server 上采用了 Map 保存注册上来的服务信息,如果配置了持久化(
ephemeral=false
)的服务会被保存到数据库中。
- 心跳检测机制:注册上来的实例每隔 5 秒就会主动上报一次自己的健康状态,发送的数据包叫做心跳包,发送心跳包的机制叫做心跳机制。如果 Nacos 服务端在 15 秒都没收到心跳,就会将实例设置为不健康,在 30 秒没收到心跳时就会将这个临时实例摘除。
- 服务消费者注册:服务消费者在启动时,向注册中心订阅自己所需的服务。
- 服务消费者获取服务提供者列表:注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 服务消费者调用服务提供者:从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 服务监控:服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
1.3 Nacos的配置中心原理
Nacos 配置中心采用C/S架构,主要由三部分组成:
- 客户端:集成在应用中的SDK
- 服务端:Nacos Server 集群
- 存储层:支持多种存储方式(默认内嵌Derby,可扩展MySQL等)
配置管理流程:

- 配置发布:
- 用户通过控制台/API发布配置,通常以键值对的形式存在。
- Nacos Server将配置持久化到存储层,同时将配置更新到内存缓存中。
- 客户端订阅:
- 应用程序(客户端)通过 Nacos 客户端库订阅所需的配置。
- 客户端库会定期(例如每30秒)从 Nacos 服务器拉取最新的配置信息。
- 配置更新推送机制:Nacos 支持两种类型的推送机制:长轮询(pull)和事件监听(push)。
- 长轮询:客户端发起配置查询请求,服务端检查配置是否有变更。有变更则立即返回;无变更则保持连接不立即返回,直到配置变更或超时(默认30秒)。客户端收到响应后再次发起请求,形成"长轮询"。
- 事件监听:客户端注册一个监听器,当配置发生变化时,Nacos 服务器会通知所有注册了该配置监听器的客户端。
- 客户端处理:
- 本地缓存:客户端将配置缓存在本地文件系统,应用启动时优先检查本地缓存。
- 监听数据更新:通过
@RefreshScope
或实现ApplicationContextAware
接口来处理配置更新。
1.4 Nacos的配置模型
Nacos 通过 Namespace、Group、Data ID 唯一定位到一个配置模型。

- namespace:命名空间(namespace)可用于进行不同环境的配置隔离。例如可以隔离开发环境、测试环境和生产环境。不同的开发人员使用同一个nacos管理各自的配置,可通过 namespace隔离。默认为空,使用
public
命名空间
- group:分组,可用来区分不同的项目或应用。不同的命名空间下,可以存在相同名称的配置分组(Group) 。默认为
DEFAULT_GROUP
,可以通过spring.cloud.nacos.config.group
配置。
- dataID:在 Nacos Config Starter 中,dataId 的拼接格式如下
prefix
默认为spring.application.name
的值,也可以通过配置项spring.cloud.nacos.config.prefix
来配置。spring.profiles.active
即为当前环境对应的 profile,详情可以参考 Spring Boot文档。当 active profile 为空时,对应的连接符-
也将不存在,dataId 的拼接格式变成${prefix}
.${file-extension}
file-extension
为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension
来配置。 目前只支持properties
类型。
使用示例:

1.5 Nacos的配置更新推送机制(pull or push)
Nacos 通过 MD5 保证版本一致性:Nacos 在配置发布后,会对配置内容生成 MD5 摘要。这个 MD5 值在服务端缓存、客户端缓存以及数据库中都会保存,作为配置版本一致性的校验依据。当配置发生变化时,通过比较 MD5 值来判断是否需要更新缓存或通知客户端。
以存储层为 Mysql 为例,
config_info
表记录了每个配置文件最新配置的原始内容(content
)和 MD5 摘要(md5
)。
his_config_info
表则记录了每个配置文件的所有历史版本。
当配置发生更新时,Nacos 通过推(push)拉(pul)结合保证配置更新的动态感知。Nacos 1.x 版本使用 HTTP 协议和 Dubbo 协议,Nacos 2.x 版本在兼容原来的 HTTP 协议的基础上开始支持 gRPC 协议,并默认使用 gRPC 协议进行通信。
- 基于 HTTP 协议,使用 8848 端口:
- pull 机制:册实例通过长轮询(Long Polling)机制从 Nacos Server 获取服务信息。
- push 机制:Nacos Server 通过检测实例心跳,在心跳超时后主动向实例推送服务信息。
- 基于 gRPC 协议,使用 9848 端口:
- 注册实例基于 gRPC协议 和 Nacos Server 建立长连接,实现更高效的双向信息传递,保证了推送的实时性和可靠性。
长轮询(Long Polling)机制是什么?
长轮询是一种伪长连接的机制,本质上仍是一个 HTTP 请求,但客户端会在请求头 Header 加上
Long-Pulling-Timeout
属性(超时通常设置 20 ~ 120 秒)。服务端接收到请求头带 Long-Pulling-Timeout
属性的请求后会等待有数据可发送或达到超时时间后再返回给客户端。这种机制可以减少客户端轮询的次数,减轻服务器的压力,但又能达到类似于长连接实时推送数据的效果。长轮询机制的过程如下:
- 客户端发起请求:客户端首次启动或需要监听配置时,向 Nacos 服务端发送一个 HTTP 长轮询请求(默认超时时间为 30秒)。
- 服务端处理请求:服务端会检查配置是否发生变更:
- 配置未变更:服务端会挂起(Hold)这个请求,直到以下两种情况之一发生:
- 配置被修改:服务端检测到对应 dataId 的配置 MD5 值变化,立即返回新配置。
- 超时(默认30秒):若超时仍无变更,返回空响应,客户端重新发起长轮询。
- 配置已变更:直接返回最新配置内容。
- 客户端响应:
- 若收到新配置,客户端更新本地缓存并触发回调(如 Spring Cloud 的
@RefreshScope
Bean 刷新)。 - 若超时无变更,客户端立即发起下一次长轮询。
普通轮询和长轮询的区别:
对比项 | 普通轮询(Short Polling) | 长轮询(Long Polling) |
工作原理 | 客户端定时(如每秒)向服务端请求配置 | 客户端发起请求后,服务端阻塞直到配置变更或超时 |
实时性 | 依赖轮询间隔,延迟高 | 近乎实时(变更后立即触发响应) |
网络开销 | 高频无效请求,浪费资源 | 仅在有变更或超时时响应,大幅减少请求量 |
1.6 Nacos的分布式一致性模型(AP or CP)
Nacos 默认采用 AP 模式,但支持 AP 与 CP 双模式切换,具体取决于实例类型(临时实例用AP,永久实例用CP)。
- AP模式(默认):Nacos 在默认情况下优先保证高可用性和分区容错性(AP),基于阿里自研的 Distro 协议,每个节点独立处理部分数据并异步同步,优先响应请求,容忍短暂数据不一致。
- CP模式:通过配置或实例类型(永久实例)可切换为 CP 模式,基于 Raft 协议,类似 Zookeeper 的 ZAB 协议,确保强一致性,但牺牲部分可用性(如选举期间服务不可用)。
适用场景:
- AP 模式:适用于对可用性要求高于强一致性的场景(如在线游戏、网站服务)。
- CP 模式:适用于金融、支付等对数据一致性要求严格的场景。
如何切换 AP 和 CP 模式?
根据注册实例的配置识别:
- 临时实例(如健康检查动态注册的服务),默认走 AP 模式。
- 永久实例(如静态配置的服务),如果实例配置
spring.cloud.nacos.discovery.ephemeral=false
,自动切换为 CP 模式。
1.7 Nacos的均衡负载机制
Nacos实现负载均衡主要是通过客户端侧的策略来完成的,主要负责将请求合理地分发给不同的服务提供者。工作原理是客户端在发起请求前,通过负载均衡算法选择一个合适的服务实例进行请求。客户端根据服务实例的健康度、负载状况等指标来决定选择哪个服务实例。

Nacos默认采用的是随机轮询的方式。内置了以下两种负载均衡策略:基于权重和基于 CMDB(低于就近访问)的负载均衡策略。
1、基于权重的负载均衡策略,这个在 Nacos 服务编辑的时候也可以看到其设置:

2、基于第三方 CMDB(地域就近访问)标签的负载均衡策略,这个可以参考官方说明文档:https://nacos.io/zh-cn/blog/cmdb.html
1.8 Nacos的雪崩保护机制
为什么要有保护阈值 ?
主要是为了防止服务雪崩的。比如说服务集群里边原本有 1000 个实例,但是现在有 999 个实例都挂了,只剩下一个实例了,那么原本 1000 个人干的活,现在就只剩一个人了,如果我们再把所有的活再派给这一个人来干,那么这个人肯定顶不住,早晚也会崩。对于咱们系统来说也是一样,如果集群实例数太少的话,这时候还把所有的流量分发过去,那就会造成服务瘫痪,进而造成上游调用这个服务的整体瘫痪,进而造成服务雪崩。所以需要保护阈值。
保护阈值是如何防止服务雪崩的 ?
当保护阈值为 true 的时候,它会将所有的请求分发给所有的服务实例(不管健康与否),不管服务实例是否已经挂掉,以此来保护所剩无几的健康实例!
示例
1、准备两个永久服务实例(对应配置文件中的
spring.cloud.nacos.discovery.ephemeral = false
),一个消费者,然后停掉一个服务。
2、将保护阈值设置为
0.5
,这时保护阈值就变为 true 了
3、重启消费者。当我们更改了权重,阈值等参数,它默认是会有缓存的,感知不到,所以需要重启消费者才能看到 nacos 的防止雪崩的策略。
4、调用消费者,发现有时候可以调通,有时候会报错,说明把请求转发到停止的实例上,说明 nacos 防止雪崩的策略生效了。

2、源码解析
2.1 源码整体结构
Nacos 源码采用多模块 Maven 项目结构,主要分为以下几个部分:
2.2 核心模块详解
1. api 模块
路径:
nacos-api
功能:
- 提供客户端使用的接口定义
- 包含所有对外暴露的API和模型定义
重要类:
NacosFactory
: 工厂类,创建各种服务实例
ConfigService
: 配置服务接口
NamingService
: 命名服务接口
Listener
: 配置监听器接口
2. client 模块
路径:
nacos-client
功能:
- 实现 api 模块定义的接口
- 客户端核心逻辑实现
重要子模块:
config
: 配置中心客户端实现
naming
: 服务发现客户端实现
auth
: 认证相关实现
3. common 模块
路径:
nacos-common
功能:
- 提供全局通用工具类和常量
- 基础模型定义
重要包:
com.alibaba.nacos.common.utils
: 工具类集合
com.alibaba.nacos.common.model
: 基础模型
com.alibaba.nacos.common.http
: HTTP客户端封装
4. config 模块
路径:
nacos-config
功能:
- 配置中心服务端实现
- 配置存储、管理和推送
重要类:
ConfigController
: 配置相关HTTP接口
ConfigService
: 配置服务核心实现
EmbeddedStoragePersistServiceImpl
: 嵌入式存储实现
5. naming 模块
路径:
nacos-naming
功能:
- 服务发现和注册中心实现
- 服务健康检查
- 集群数据同步
重要类:
NamingController
: 服务发现相关HTTP接口
ServiceManager
: 服务管理核心类
HealthCheckProcessor
: 健康检查处理器
DistroProtocol
: 集群数据同步协议
6. core 模块
路径:
nacos-core
功能:
- 系统核心功能实现
- 通用基础框架
重要子模块:
cluster
: 集群管理
auth
: 权限认证
notify
: 事件通知
storage
: 存储抽象层
7. console 模块
路径:
nacos-console
功能:
- Nacos 控制台前端代码
- 管理界面实现
特点:
- 基于 Vue.js 实现
- 提供可视化配置管理界面
2.3 重要设计模式
1. 工厂模式
体现:
NacosFactory
提供各种服务的创建
- 模块间通过接口交互,实现可插拔
2. 观察者模式
体现:
- 配置变更监听机制
- 服务实例变化通知
3. 责任链模式
体现:
- 请求处理过滤器链
- 健康检查处理器链
2.4 关键流程源码位置
1. 配置获取流程
- 客户端入口:
nacos-client.ConfigService.getConfig()
- 服务端入口:
nacos-config.ConfigController.getConfig()
2. 服务注册流程
- 客户端入口:
nacos-client.NacosNamingService.registerInstance()
- 服务端入口:
nacos-naming.NamingController.register()
3. 服务发现流程
- 客户端入口:
nacos-client.NacosNamingService.getAllInstances()
- 服务端入口:
nacos-naming.InstanceController.list()
4. 配置长轮询流程
- 客户端:
nacos-client.ClientWorker.LongPollingRunnable
- 服务端:
nacos-config.ConfigController.listener()
2.5 调试建议
- 配置中心调试:
- 重点关注
nacos-config
和nacos-client.config
模块 - 关键断点:
ConfigController
和ClientWorker
- 服务发现调试:
- 重点关注
nacos-naming
和nacos-client.naming
模块 - 关键断点:
NamingController
和HostReactor
- 日志配置:
2.6 扩展点
- 插件开发:
- 可扩展
nacos-plugin
模块 - 支持自定义存储、认证等插件
- 自定义模块:
- 基于
nacos-api
实现自定义客户端 - 扩展
nacos-core
实现特定功能
- Author:mcbilla
- URL:http://mcbilla.com/article/1d085c7d-7c1d-80f0-ac4a-e9560b8bce13
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!