Nacos源码剖析-服务注册与发现(临时实例AP模式)
2024-09-06 15:00:25 0 举报
Nacos源码剖析-服务注册与发现(临时实例AP模式)
作者其他创作
大纲/内容
notifier.run()
调用server的实例注册接口(HttpMethod.POST)
无限循环监听消息队列变化,当有数据变化时,更新服务列表并发送服务信息变更的消息。
注册中心
serverProxy.sendBeat(beatInfo)
数据返回
getPushService().serviceChanged(service)
Notifier.BlockingQueue
deleteIP(instance)
instance.setHealthy(false)
ClientBeatCheckTask
调用server的实例发送心跳接口(HttpMethod.PUT)
(spring完成refresh上下文后会调用这个方法)
service.init()
1、获取服务,初次获取一定为空
/instance
将临时的注册实例更新到了cluster的ephemeralInstances 属性上去,服务发现查找临时实例最终从内存里找到的就是这个属性
调用server的服务发现接口(HttpMethod.GET)
/instance/beat
hostReactor.getServiceInfo
tasks.take()
3、服务发现
buildBeatInfo
实现ApplicationListener接口的类,spring容器启动时会调用处理事件方法
NacosServiceRegistry
instance.setLastBeat(System.currentTimeMillis())
@Bean
getService
serviceManager.registerInstance
getPushService().serviceChanged(this)
AbstractAutoServiceRegistration
allInstances.addAll(persistentInstances);allInstances.addAll(ephemeralInstances);
如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)
客户端
serviceInfoMap(客户端实例缓存map)
将注册实例信息更新到注册表内存结构里去
serviceManager.removeInstance
DistroConsistencyServiceImpl.init()
源码精髓:nacos这个更新注册表内存方法里,为了防止读写并发冲突,大量的运用了CopyOnWrite思想防止并发读写冲突,具体做法就是把原内存结构复制一份,操作完最后再替换回真正的注册表内存里去。
client
1、服务注册
InstanceController.list
ephemeralInstances = toUpdateInstances
UpdateTask
this.getRegistration()就是NacosRegistration的实例
发送事件
创建内存注册表结构
服务注册
HealthCheckReactor.scheduleCheck(clientBeatCheckTask)
NamingResponseCode.OK
serviceRegistry.register(this.getRegistration())
返回的就是注册时写入的实例属性
bind(event)
serviceRegistry就是NacosServiceRegistry的实例
putService(service)
进行udp的广播 udpSocket.send(ackEntry.origin)
serverProxy.registerService
BeatTask
如果缓存为空,调用server接口获取最新服务数据
NacosNamingService.registerInstance
ephemeralConsistencyService
ApplicationListener
获取客户端的服务实例缓存信息
实现
1、服务注册、心跳
if (instance.isEphemeral()){添加一个延时执行的定时心跳任务BeatTask}
InstanceController.register
源码精髓:很多开源框架为了提升操作性能会大量使用这种异步任务及内存队列操作,这些操作本身并不需要写入之后立即成功,用这种方式对提升操作性能有很大帮助
构建心跳数据,里面有个心跳周期5秒参数
阿里自己实现的AP模式的Distro协议
spring-cloud-alibaba-nacos-discovery.jar里的spring.factories文件里的EnableAutoConfiguration对应NacosServiceRegistryAutoConfiguration
NacosServiceRegistryAutoConfiguration
NacosAutoServiceRegistration
getPushService().serviceChanged(service);
调用server的实例注销接口(HttpMethod.DELETE)
1、将注册实例更新到内存注册表
将新注册实例加入对应服务service的实例列表里去
注册完成
start()
putServiceAndInit(service)
如果服务是非健康的状态,那我们需要通知客户端需要更新一下本地服务状态
发送事件后用udp协议通知客户端进行服务状态更改
解析服务结果
service.srvIPs
如果返回NamingResponseCode.RESOURCE_NOT_FOUND,则服务第一次启动需要进行注册
InstanceController.beat
.applicationContext.publishEvent
/instance/list
doSrvIPXT
启动
将service对应的全量实例instances写入内存注册表
beatReactor.addBeatInfo
定时任务发送心跳,默认5秒
如果某个实例超过15秒没有收到心跳,则将它的healthy属性置为false
监听事件发送通知客户端
初始化异步线程Nofifier
1.2、心跳
每隔10秒定时获取服务端最新服务数据并更新到本地的任务
服务提供者
DelegateConsistencyServiceImpl.put
1.1、服务注册
往阻塞队列tasks里放入注册实例数据
源码入口
onApplicationEvent
NacosRegistration
2、设置并初始化服务
立即开启一个任务ClientBeatProcessor,更新客户端实例的最后心跳时间
如果实例不存在重新注册(如网络不通导致实例在服务端被下线或服务端重启临时实例丢失)
mapConsistencyService(key)
createEmptyService
健康状态检测
循环从阻塞队列tasks里拿实例数据处理
Server
继承
定时5秒执行一次任务
发布服务变化事件
GlobalExecutor.submitDistroNotifyTask(notifier)
延时执行的定时任务更新客户端的服务缓存
如果是临时实例数据
service.processClientBeat(clientBeat)
2、心跳机制
循环订阅服务的客户端
register()
PushService#onApplicationEvent
0 条评论
回复 删除
下一页