nacos服务注册源码浅析

nacos服务注册源码浅析

流程从NacosDiscoveryAutoConfiguration自动配置类开始,它由spring-cloud-alibaba-nacos-discovery.jar里的spring.factories文件注册,是整个 Nacos 服务发现的启动入口。配置类中通过@Bean注入了NacosServiceRegistryNacosRegistrationNacosAutoServiceRegistration三个核心 Bean。

其中,NacosAutoServiceRegistration继承自AbstractAutoServiceRegistration,并实现了ApplicationListener接口,会监听 Spring 容器的事件。当容器启动完成后,会触发onApplicationEvent方法,依次执行bindstartregister流程,最终调用serviceRegistry.register()方法,把NacosRegistration携带的服务信息注册到 Nacos 服务端。

接下来看源码,首先进入这里

带auto,名字和依赖很像,大概率这个是核心类 实现了listenr接口,直接看相关方法

执行bind

如图,实际源码都在调用图里,接下来不一步一步跟了

客户端调用NamingService.registerInstance后,会先为临时实例添加延迟执行的BeatTask心跳任务,再通过 POST 请求调用/instance接口完成注册。

服务端收到请求后,由InstanceController.register处理,创建服务、写入内存注册表并同步集群数据。客户端的心跳任务启动后,会定时通过 PUT 请求调用/instance/beat接口,服务端则在InstanceController.beat中更新实例的最后心跳时间,若实例不存在还会触发重新注册,实现故障自愈。

服务端收到注册请求后,由InstanceController.register入口开始处理,serviceManager.registerInstance会先检查服务是否存在,不存在则通过createEmptyService创建服务,并调用putServiceAndInit初始化:一方面把服务写入serviceMap内存注册表,另一方面执行service.init()启动后续任务。接着addInstance会把实例加入服务的实例列表,再通过consistencyService.put将数据写入一致性存储,完成注册信息的持久化与集群同步。

注册完成后,service.init()会触发ClientBeatCheckTask定时任务,这是服务端的核心健康检查逻辑。任务启动时,会通过distroMapper.responsible根据服务名哈希取模,选出集群中负责该服务健康检查的节点。这个任务会定期扫描实例:超过 15 秒没收到心跳,就把实例标记为不健康;超过 30 秒没收到心跳,就直接剔除实例,客户端恢复心跳后会自动重新注册。

同时,服务端还有ServerStatusReporterServiceManager.init启动的集群同步任务,前者负责同步集群节点状态,后者负责把注册信息同步到其他节点,确保集群数据一致性,也保障了健康检查任务节点的选择准确性。

当服务端收到注册请求后,会调用 DistroConsistencyServiceImpl.put 方法,第一步先把实例数据更新到本地内存的 dataStore 中,同时往阻塞队列里添加任务,通知监听器处理实例变更。监听器 Service 收到变更通知后,会把实例信息更新到 ephemeralInstances 临时实例列表里,完成内存注册表的更新,这样后续服务发现时就能读到最新的实例信息。

第二步是集群同步,distroProtocol.sync 会把实例信息同步到 Nacos 集群的其他节点,同步任务会被提交到延迟任务执行引擎中排队执行,确保集群各节点数据一致。同时,服务端还会通过 PushService 发布服务变更事件,以 UDP 方式把实例变动通知给订阅了该服务的客户端,让客户端能及时更新本地服务缓存。

当服务端需要同步实例数据时,会先通过distroProtocol.sync发起请求,同步任务会被提交到DistroTaskEngineHolder的延迟执行引擎中,由DistroDelayTaskExecuteEngine调度处理。引擎会按固定延迟执行ProcessRunnable,通过DistroDelayTaskProcessor.process解析任务,再将任务交给DistroSyncChangeTask处理。

任务最终会通过NamingProxy.syncData调用目标节点的/distro/datum接口(PUT 请求)发送数据。同步过程中如果失败,会进入handleFailedTask重试流程,确保数据可靠同步到集群其他节点,避免因网络波动导致数据不一致。

相关推荐
森蓝情丶17 分钟前
我给 AI 搭了个法庭:一个前端仔的 LangGraph 实战全记录
前端·后端
JensCS猿21 分钟前
从 Spring Boot 回看 SSM 框架:手动挡与自动挡的驾驶哲学
后端
爱勇宝21 分钟前
干了近 8 年,一夜之间被裁:AI 时代,程序员最该害怕的不是 AI
前端·后端·程序员
科米米30 分钟前
嵌入式日志模块
后端
血小溅1 小时前
三大 AI 编码框架深度对比:GSD vs OpenSpec vs Superpowers
人工智能·后端
ThanksGive1 小时前
层级时间轮看门狗
后端
GetcharZp2 小时前
告别繁琐命令行!这款容器可视化神器,让 Docker/K8s 管理变得如此简单
后端
铁皮饭盒5 小时前
bun直接tsx,优雅!
javascript·后端
Cosolar6 小时前
藏在 Claude Code 里的极致浪漫:完整 187 条 Spinner Verbs 全收录
后端·程序员·代码规范
Csvn6 小时前
Linux 防火墙管理 — firewalld 实战
后端