Nacos1.1.4注册中心源码分析
2025-02-26 14:48:53 12 举报
此图是我对Nacos源码注册中心的理解,供大家学习交流。更多干货内容,欢迎关注我的公众号:Fox爱分享
作者其他创作
大纲/内容
queue.offer(key)
集群模式
DistroConsistencyServiceImpl#init
HealthCheckReactor.scheduleCheck(clientBeatCheckTask)
发布服务变化事件
服务实例数据提交接口
raftStore.write(datum)
ClientBeatCheckTask
更新注册实例到注册表中
心跳续约
deregisterInstance
向Nacos集群的随机一个节点发送HTTP请求
allInstances.addAll(persistentInstances); allInstances.addAll(ephemeralInstances);
心跳检测任务
将注册实例更新到内存注册表
group::serviceName
Instance
否
Nacos服务注册表结构
tasks.take()
NacosServerList#getUpdatedListOfServers
spring-cloud-alibaba-nacos-discovery-2.1.0.RELEASE.jar!/META-INF/spring.factories
instance.isEphemeral()
每隔5s执行ClientBeatCheckTask客户端心跳检查任务
服务注册
缓存service到双Map结构的serviceMap中
取消注册实例
@Bean
InstanceController#register
ApplicationListener
/nacos/v1/ns/distro/datum
RaftController#onPublish
服务发现接口
从serviceInfoMap中获取客户端的实例缓存信息
TaskDispatcher
instance.setLastBeat(System.currentTimeMillis())
NacosNamingService
实例超过15s没有收到心跳
subscribe
selectInstances
NacosServiceRegistry
获取Service
返回注册时写入的实例数据
Nacos服务端心跳接口
InstanceController#list
利用CountDownLatch实现raft协议节点数据同步逻辑,必须集群半数以上节点(peers.size() / 2 + 1)写入成功,客户端才返回成功
心跳续约任务
HttpClient.asyncHttpPostLarge
同步实例数据到集群其他节点
异步任务更新内存注册表
ClientBeatProcessor#run
listener.onDelete(datumKey)
添加注册实例到阻塞队列
implements
InstanceController#beat
获取服务实例列表
立即开启一个任务ClientBeatProcessor,更新最后一次心跳时间
HttpMethod.POST
putServiceAndInit(service)
是
putService(service)
DistroController#onSyncDatum
Notifier#run
如果注册的实例达到一定数量(默认1000)或者距离上一次同步达到一定时间(默认2s)就批量同步给集群其他节点
deleteIP(instance)
Ribbon的调用逻辑
判断是否是临时实例,默认为true
调用服务注册接口
service.init()
循环从阻塞队列中取出实例数据处理
获取实例列表
ClientBeatCheckTask#run
getAllInstances
服务端注册接口
将全量实例写入内存注册表
executor.submit(notifier)
如果实例不存在重新注册比如:网络问题导致服务下线或者服务端重启临时实例丢失
NamingService
TaskScheduler#run
leader节点发布服务,更新注册实例到内存和磁盘上
提供Nacos的注册功能
HealthCheckTask
keys.add(key)
key: com.alibaba.nacos.naming.iplist.ephemeral.public##DEFAULT_GROUP@@service-order
往阻塞队列中放入注册的实例数据
taskDispatcher.addTask(key)
心跳检查任务
服务实例同步接口
服务心跳续约
发送心跳请求的任务
添加新注册的实例到服务列表中
2. 同步实例信息到nacos集群其他节点
clusterName
如果缓存为空,调用服务接口获取最新的实例数据
register()
删除
延时1s执行定时任务,每隔1s从服务端获取最新实例数据,并缓存到本地
HostReactor
persistentInstances
registerInstance
HealthCheckReactor.scheduleCheck(checkTask)
获取所有实例(主动拉取)
反射创建
服务剔除
NacosAutoServiceRegistration
AbstractAutoServiceRegistration
DynamicServerListLoadBalancer#updateListOfServers
实现Nacos的自动注册功能
失败重试
start()
ApplyAction.CHANGE
从双Map结构中获取服务,如果没有创建服务
namespace
KeyBuilder.matchEphemeralKey(key) ? ephemeralConsistencyService : persistentConsistencyService
更新
reqAPI(UtilAndComs.NACOS_URL_BASE + \"/instance/beat\
RaftConsistencyServiceImpl
初始化NamingService
NacosRegistration
ephemeralInstances = toUpdateInstances
实现了Spring事件监听机制,Spring容器启动过程中会调用onApplicationEvent方法
DistroConsistencyServiceImpl#put
extends
instance.setHealthy(false)
if (dataSize == partitionConfig.getBatchSyncKeyCount() || (System.currentTimeMillis() - lastDispatchTime) > partitionConfig.getTaskDispatchPeriod())
retrySync(syncTask)
Nacos命名服务提供了消费端服务发现注册订阅等功能
添加一个定时心跳任务
onApplicationEvent(WebServerInitializedEvent event)
更新实例
/v1/ns/raft/datum/commit
NacosDiscoveryAutoConfiguration
注册服务实例
serverProxy.sendBeat(beatInfo)
DistroConsistencyServiceImpl
服务健康检查任务
BeatTask#run
Cluster
当前节点是否为Leader节点?
RaftCore
ApplyAction.DELETE
HealthCheckReactor.scheduleNow(clientBeatProcessor)
nacosDiscoveryProperties.namingServiceInstance()
httpClient.execute(httpPut)
ServiceRegistry
/nacos/v1/ns/instance/list
发送请求
GlobalExecutor.submitDataSync
临时实例, AP模式的Distro协议
HostReactor.UpdateTask#run
从缓存中获取实例信息
延时执行的定时任务,更新客户端的服务实例缓存
1. 将注册实例更新到内存注册表
/nacos/v1/ns/instance
根据条件获取服务注册实例
实例超过30s没有收到心跳
GlobalExecutor.submitTaskDispatch(taskScheduler)
数据持久化到本地磁盘
Cluster#allIPs()
hostReactor.getServiceInfo
调用心跳接口
更新临时实例,服务发现查找临时实例会从cluster的ephemeralInstances获取
curl localhost:8002/user/getById/1
源码入口
执行实例数据批量同步任务
client
getPushService().serviceChanged(this)
RaftStore
服务订阅
注册服务实例,通过Registration构建Instance
serviceRegistry.register(getRegistration())
循环从阻塞队列中获取实例进行处理
Service
ephemeralInstances
服务实例同步
/nacos/v1/ns/instance/beat
每隔5s定时发送心跳
TaskDispatcher#init
Service#init
service.processClientBeat(clientBeat)
收藏
收藏
0 条评论
下一页