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的工作原理
以这个架构图图为例

流程:
- 服务容器负责启动,加载,运行服务提供者。
- 服务提供者在启动时,向注册中心注册自己提供的服务。临时实例每隔 5 秒就会主动上报一次自己的健康状态,发送的数据包叫做心跳包,发送心跳包的机制叫做心跳机制。如果 Nacos 服务端在 15 秒都没收到心跳,就会将实例设置为不健康,在 30 秒没收到心跳时就会将这个临时实例摘除。
- 服务消费者在启动时,向注册中心订阅自己所需的服务。心跳机制同上。
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
1.3.1 注册信息的保存(serviceMap)
Nacos Server上采用了Map保存注册上来的服务信息,如果配置了持久化(
ephemeral=false
)的服务会被保存到数据库中。1.3.2 推拉结合保证本地服务实例列表的动态感知
- Nacos在配置发布后,会对配置内容生成MD5摘要。这个MD5值在服务端缓存、客户端缓存以及数据库中都会保存,作为配置版本一致性的校验依据。当配置发生变化时,通过比较MD5值来判断是否需要更新缓存或通知客户端。
- Nacos 1.x版本,注册实例基于Http协议通过pull的方式定期轮询Nacos Server获取服务信息。Nacos Server通过检测实例心跳,在心跳超时后通过push的方式主动向实例推送服务信息。
- Nacos 2.x版本后,注册实例基于gRPC协议和Nacos Server建立长连接,实现更高效的双向信息传递,保证了推送的实时性和可靠性。
1.3 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文档file-extension
为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension
来配置。 目前只支持properties
类型。
注意,当 active profile 为空时,对应的连接符
-
也将不存在,dataId 的拼接格式变成 ${prefix}
.${file-extension}
使用示例:

1.4 Nacos的均衡负载机制
Nacos实现负载均衡主要是通过客户端侧的策略来完成的,主要负责将请求合理地分发给不同的服务提供者。工作原理是客户端在发起请求前,通过负载均衡算法选择一个合适的服务实例进行请求。客户端根据服务实例的健康度、负载状况等指标来决定选择哪个服务实例。

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

2、基于第三方 CMDB(地域就近访问)标签的负载均衡策略,这个可以参考官方说明文档:https://nacos.io/zh-cn/blog/cmdb.html
1.5 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!