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重试流程,确保数据可靠同步到集群其他节点,避免因网络波动导致数据不一致。

相关推荐
SimonKing1 小时前
Java程序员接入AI的另一种姿势:LangChain4j
java·后端·程序员
右耳朵猫AI1 小时前
Rust技术周刊 2026年第20周
开发语言·后端·rust
苏三说技术1 小时前
别再用MySQL了,AI时代这个数据库更香!
后端
杨运交1 小时前
[025][Web模块]基于 Spring Boot 的请求日志过滤器设计与实现
前端·spring boot·后端
IT_陈寒1 小时前
React的useEffect里设状态?我又踩雷了
前端·人工智能·后端
云浪2 小时前
搞懂 Go WaitGroup:一篇文章彻底理解并发等待机制
后端·go
一 乐2 小时前
在线考试|基于Springboot的在线考试管理系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·毕设·在线考试管理系统
右耳朵猫AI2 小时前
Golang技术周刊 2026年第20周
开发语言·后端·golang
我是一颗柠檬2 小时前
【Redis】有序集合与位图Day5(2026年)
数据库·redis·后端·缓存