nacos源码学习--服务变动

  服务实例发生变动的时候, 如果仅靠客户端 定时任务向注册中心拉取实例, 会有五秒钟的延时

  Nacos为之优化, 做了一个服务端主动推送

---------------Notifier.run()-----------------
405行 handle(pair); → 432行 listener.onChange(datumKey, dataStore.get(datumKey).value); → Service.onChange() 197行
→ updateIPs(value.getInstanceList(), KeyBuilder.matchEphemeralInstanceListKey(key)); → Service 282行 getPushService().serviceChanged(this); 
→ 追到了PublishEvent 源码

--------------publish Event-----------------
public void serviceChanged(Service service) {
// merge some change events to reduce the push frequency:
if (futureMap
.containsKey(UtilsAndCommons.assembleFullServiceName(service.getNamespaceId(), service.getName()))) {
return;
}

// @ZyxNote服务变动 发布事件 服务变化
this.applicationContext.publishEvent(new ServiceChangeEvent(this, service));
}

-----------Listen Event Service121行------------------------
// @ZyxNote服务变动 监听onChange Publish Event
@Override
public void onApplicationEvent(ServiceChangeEvent event);
172行 udpPush(ackEntry); 服务端向客户端发起UDP请求
  Nacos的这种推送模式 比起ZK的TCP方式来说 节约了资源,增强了效率 Client收到Server的消息之后 会给Server一个ACK,如果一定时间内Server没有接收到ACK,会进行重发
  当超过重发之后,不再重发 尽管UDP会丢包,但是仍然有定时任务的轮训兜底 不怕丢了数据

-----------------集群间同步状态定时任务-------------------
// @ZyxNote集群服务变动 init() 两个任务
@PostConstruct
public void init() {
  // 集群间发送心跳
GlobalExecutor.registerServerStatusReporter(new ServerStatusReporter(), 2000);
GlobalExecutor.registerServerInfoUpdater(new ServerInfoUpdater());
}]
-----------------集群间同步实例健康状态定时任务-------------------
ServiceManager.init() → ServiceReporter.run()
-----------------集群间新增实例健康状态定时任务-------------------

DistroConsistencyServiceImpl.distroProtocol.sync → sync data → DistroConsistencyServiceImpl.processData()
在此方法中 最后还是调用了onPut方法

ps~~:一个Raft协议动画演示网站 http://thesecretlivesofdata.com/raft/


















posted @ 2021-10-09 12:10  却道。此心安处是吾乡  阅读(130)  评论(0编辑  收藏  举报