本文收录于专栏 Nacos 中 。
文章目录
前言
前边几篇文章我们一起看了Nacos
中客户端注册时的服务端相关源码,在各个流程上做了简单梳理。这里我们做一个整体上的总结。
流程
一、接收客户端请求,发布客户端注册事件
InstanceRequestHandler
接收所有实例注册、注销相关的请求InstanceRequestHandler
处理注册请求时,会调用EphemeralClientOperationServiceImpl
中的registerInstance
方法- 将当前封装客户端信息的
Service
添加到ServiceManager
中。ServiceManager
中会根据namespace
缓存当前客户端Service
类 NotifyCenter
发布ClientOperationEvent.ClientRegisterServiceEvent
事件
- 将当前封装客户端信息的
二、处理客户端注册事件
ClientServiceIndexesManager
中的onEvent
处理客户端操作事件- 当前事件为客户端注册事件
ClientOperationEvent.ClientRegisterServiceEvent
时:- 发布新事件
ServiceEvent.ServiceChangedEvent
- 发布新事件
NamingSubscriberServiceV2Impl
中的onEvent
处理ServiceEvent.ServiceChangedEvent
事件:- 当前客户端
Service
被封装成PushDelayTask
添加到延迟任务处理引擎PushDelayTaskExecuteEngine
中
- 当前客户端
三、任务处理引擎
- 任务处理引擎
PushDelayTaskExecuteEngine
中含有一个单线程延迟线程池,间隔指定时间去处理缓存的任务ConcurrentHashMap<Object, AbstractDelayTask> tasks
- 延时线程池处理任务时,会使用任务处理器
PushDelayTaskProcessor
处理任务- 将客户端
Service
组装成PushExecuteTask
,然后使用NamingExecuteTaskDispatcher
做任务分发,其实就是将任务添加到另一个任务处理引擎NacosExecuteTaskExecuteEngine
中 - 调用
NacosExecuteTaskExecuteEngine
的添加任务方法addTask
时,会将当前任务交由TaskExecuteWorker
处理
- 将客户端
四、执行任务(PushDelayTask)
TaskExecuteWorker
继承了Thread
,其内部维护了一个BlockingQueue<Runnable> queue
,重写的run
方法会不断去扫描队列,然后执行队列中的任务task.run();
- 这里我们要注意队列中的数据类型是
Runnable
,所以从队列中获取任务之后可以直接调用任务的run
方法 - 结合前边的流程,那么这里的任务其实是
PushExecuteTask
,一个也继承了Thread
,在重写的run
方法中会处理Service
推送到订阅者的逻辑。
- 这里我们要注意队列中的数据类型是
总结
以上,我们简单梳理了客户端注册到Nacos
的大致流程,并且给出了其中一些关键的处理类。在前几篇源码分析的文章中,我们可以看出,客户端注册的流程设计里使用了大量的模版模式 去封装局部逻辑。这使得在简单归纳源码之后,整个注册逻辑在流程上较为清晰可见。同时,Nacos
面向事件而封装的NotifyCenter
也让人印象深刻。
保持怀疑的眼光去审视时,也要有一颗学徒的心不断汲取优秀的设计思想和实现。
关于Nacos
2.X版本使用grpc
的相关逻辑,这里不再赘述,网上关于grpc
的文章多如牛毛。
enjoy~