Nacos服务注册发现源码
2022-10-21 17:52:27 2 举报
Nacos服务注册发现源码是一个基于Spring Cloud实现的服务注册与发现组件。它提供了一组简单易用的特性集,包括服务注册、服务发现、动态配置和动态 DNS 等。Nacos采用客户端/服务器端架构,客户端负责发起请求并处理响应,而服务器端则负责存储和管理数据。在服务注册方面,Nacos支持多种注册方式,包括HTTP、Dubbo和gRPC等。在服务发现方面,Nacos支持基于权重的负载均衡和服务路由等功能。此外,Nacos还提供了丰富的API和可视化界面,方便用户进行管理和监控。总之,Nacos是一个非常强大且易于使用的服务注册发现组件,适用于各种规模的分布式系统。
作者其他创作
大纲/内容
consistencyService.onPut
senvicelnfoMap(客户端实例缓存map)
如果缓存为空,调用server接口获取最新服务数据
PersistentConsistencyServiceDelegateImpl
Set<Instance>
临时实例,不持久化,放内存,APinstance.ephemeral=true
UpdateTask
DistroSyncChangeTask.run()
BeatReactor内部维护定时线程池初始大小为6
临时实例
namespace
NamingProxy.getAllData(targetServer)
新节点启动后,从集群其它节点一次性同步数据
本节点是否为leader
Instance
DistroController.onSyncDatum
NamingService.registerlnstance
PersistentNotifier.onEvent(ValueChangeEvent event)
group:serviceName
distroProtocol.sync
notifier.run()
PersistentConsistencyService
checkTask = new HealthCheckTask(this)
HttpClient.asyncHttpPostLarge
Nacos集群新节点启动时向其它节点拉取数据同步流程
ClientBeatCheckTask
NacosServiceRegistry
N
deletelp(instance)
bind(event)
Y
onApplicationEvent
ephemerallnstances
service.processClientBeat(clientBeat)
往阻塞队列tasks里放入注册实例数据
updatelPs(value.getlnstanceList0.KeyBuilder.matchEphemerallnstanceListKey(key))
putService(service)
executorService.schedule(newBeatTask())
startLoadTask()
serverProxy.sendBeat(beatlnfo)【缺省5s/次】
client
发布事件ValueChangeEvent更新内存注册表
clusterName
HealthCheckReactor.scheduleCheck(clientBeatCheckTask)
taskQueue.add(beat)
永久实例
serviceRegistry就是NacosServiceRegistry的实例
/raft/datum/commit
同步不成功重试
NacosNamingService.getAlllnstances()
Distro协议
构造方法里开启数据同步任务
createEmptyService
task.run()
DelegateConsistencyServicelmpl
(DistroDelayTaskProcessor)processor.process(task)
lnnerWorker.run()
服务注册
/instance/beat
放入阻塞队列
最后会更新lastRefTime为当前时间
如果注册的实例达到—定数量(默认1000)或者距离上一次同步达到一定时间(默认2s)就批量同步给集群其他节点
移临时的注册实例更新到了cluster的ephemerallnstances属性上去,服务发现查找临时实例最终从内存里找到的就是这个属性
servicevanagergetService(namespaceld. serviceName)
raftProxy.proxyPostLarge(将注册请求转发到集群的leader节点
CopyOnWrite
调用server的实例同步接口(HttpMethod.PUT)
EphemeralConsistencyService
缓存?
nacos注册表结构
循环从阻塞队列tasks里拿实例数据处理
返回的就是注册时写入的实例属性
利用CountDownLatch实现了—个简单的raft协议写入数据的逻辑,必须集群半数以上节点写入成功才会给客户端返回成功
是临时实例
DistroConsistencyServiceImpl
this.port.compareAndSet()
lnstanceController.beat()
instance.setHealthy(false)Applicationutils.publishEvent()
Serivce
register()
naming工程
persistentConsistencyService
延时1s执行的定时任务更新客户端的服务缓存
DistroTaskEngineHolder
hostReactor.getServicelnfo
创建内存注册表结构
Raft协议
Cluster
ApplicationListener
周期为2000 + 5000毫秒内的随机数检测异常只会标记为不健康,不会删除宁可不删除也不能删错
获取服务列表
DistroConsistencyServicelmpl.init0
如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)
instance.setLastBeat(System.currentTimeMillis())
临时实例(默认)
service.srvlPs
serviceRegistry.register(this.getRegistration())
实现
if (instance.isEphemeral())
beatReactor.addBeatlnfo
listener.onDelete(datumKey)
1、将注册实例更新到内存注册表
udp方式将服务变动通知给订阅的客户端
NotifyCenter.publishEvent
alllnstances.addAll(persistentlnstances);alllnstances.addAll(ephemerallnstances);
ephemeralConsistencyService
执行定时任务 5s延时 5s频率
获取客户端的服务实例缓存信息
服务器注册接口
/distro/datums
调用server的实例发送心跳接口(HttpMethod.POST)
/instance【注册实例】
ConsistencyService
DistroProtocol
服务发现
lnstanceController.list()
心跳实例是否存在
@Bean
调用入口
/distro/datum
CAS
queue.take()
transportAgent.getDatumSnapshot(each.getAddress())
doSrvlPXT
putServiceAndlnit(service)
addinstance()
PushService.onApplicationEvent(ServiceChangeEvent event)
发布服务变化事件
ApplyAction.DELETE
start()
spring-cloud-alibaba-nacos-discovery.jar里的spring.fatories文件里的EnableAutoConfiguration对应NacosDiscoveryAutoConfiguration
queue.put(task)
AbstractAutoServiceRegistration
从nacos官方文档上找到的客户端服务发现的代码。实际span style=\"font-size: inherit;\
ProcessRunnable.run()
server
run()
DelegateConsistencyServiceImpl
GlobalExecutor.submitDistroNotifyTask(notifier)
startDistroTask()
tasks.take()
临时实例,委托后采用nacos自定义的Distro协议实现集群一致性
NacosDiscoveryAutoConfiguration
将注册实例信息更新到注册表内存结构里去
serviceManager.registerlnstance
继承
GlobalExecutor.submitLoadDataTask
调用server的实例发送心跳接口(HttpMethod.PUT)
handleFailedTask()
完成注册表更新,一级集群数据同步
NacosRegistration
永久实例,委托后采用简化的Raft协议来实现集群一致性
loadAllDataSnapshotFromRemote(each)
lnstanceController.register()
raftStore.write(datum)
ApplyAction.CHANGE
this.getRegistration()就是NacosRegistration的实例
put()
如果实例不存在重新注册(如网络不通导致实例在服务端被下线或服务端重启临时实例丢失)
定时1s获取服务端最新服务数据并更新到本地的任务
调用server的实例发送心跳接口(HttpMethod.GET)专入的参数里有客户端的udp端口,这个是方便服务端实例有变化了通过udp方式同步给客户端
serverProxy.registerService
listener.onChange
同步实例信息给集群其他节点
同步写实例数据到文件
dataStore.put(kev.datum)
BeatTask
istance/list
new DistroDelayTaskExecuteEngine()
DistroLoadDataTask.run()
persistentlnstances
2同步实例信息到nacos server集群其它节点
ephemerallnstances=toUpdatelnstances
service.init()
return KeyBuilder.matchEphemeralKey(key)? ephemeralConsistencyService : persistentConsistencyService;
接收处理心跳
load()
getPushService().serviceChanged(this)
worker.process(task)
0 条评论
回复 删除
下一页