«

Nacos源码学习计划-Day25-Nacos2.x-服务的注销

ZealSinger 发布于 阅读:38 Java


今天来看服务下线的源码部分,也就是当注册到Nacos上的服务终止的时候进行的逻辑操作

客户端的相关操作

怎么找到对应的代码块这边我们就不过多表述了,肯定还是主要围绕AbstractAutoServiceRegistration这个自动注册相关的类进行的操作

我们可以看到,在这个类下,有一个@PreDestroy注解标识的销毁方法,该方法内部就是调用了stop方法

image-20260121171102948

stop方法的逻辑如下

可以看到,整体内容和Nacos1.4版本的逻辑操作相差不大,对客户端保存的注册实例遍历然后依次执行一些注销前置操作,注销后置操作等等

private List<RegistrationLifecycle<R>> registrationLifecycles = new ArrayList<>();

public void stop() {
if (this.getRunning().compareAndSet(true, false) && isEnabled()) {

this.registrationLifecycles.forEach(
registrationLifecycle -> registrationLifecycle.postProcessBeforeStopRegister(getRegistration()));
deregister();
this.registrationLifecycles.forEach(
registrationLifecycle -> registrationLifecycle.postProcessAfterStopRegister(getRegistration()));
if (shouldRegisterManagement()) {
this.registrationManagementLifecycles
.forEach(registrationManagementLifecycle -> registrationManagementLifecycle
.postProcessBeforeStopRegisterManagement(getManagementRegistration()));
deregisterManagement();
this.registrationManagementLifecycles
.forEach(registrationManagementLifecycle -> registrationManagementLifecycle
.postProcessAfterStopRegisterManagement(getManagementRegistration()));
}
this.serviceRegistry.close();
}
}

在最后deregisterManagement()中最后会发送一个Rpc的请求发送给服务端

image-20260121172019699

服务端处理Rpc请求

依旧是先找到对应的Handler,依旧是熟悉的switch-case对于不同类型的区分处理

image-20260121172226490

对应的deregisterInstance()方法的代码如下

private InstanceResponse deregisterInstance(Service service, InstanceRequest request, RequestMeta meta) {
   clientOperationService.deregisterInstance(service, request.getInstance(), meta.getConnectionId());
   return new InstanceResponse(NamingRemoteConstants.DE_REGISTER_INSTANCE);
}


@Override
public void deregisterInstance(Service service, Instance instance, String clientId) {
   if (!ServiceManager.getInstance().containSingleton(service)) {
       Loggers.SRV_LOG.warn("remove instance from non-exist service: {}", service);
       return;
  }
   Service singleton = ServiceManager.getInstance().getSingleton(service);
   // 获取 client 对象
   Client client = clientManager.getClient(clientId);
   if (!clientIsLegal(client, clientId)) {
       return;
  }
   // 移除 instance 信息,在这里面会操作 publishers 那个Map,以及发 ClientChangedEvent 事件,来同步集群节点
   InstancePublishInfo removedInstance = client.removeServiceInstance(singleton);
   client.setLastUpdatedTime();
   if (null != removedInstance) {
       // 发布客户端注销事件
       NotifyCenter.publishEvent(new ClientOperationEvent.ClientDeregisterServiceEvent(singleton, clientId));
       NotifyCenter.publishEvent(
               new MetadataEvent.InstanceMetadataEvent(singleton, removedInstance.getMetadataId(), true));
  }
}

对于客户端注销事件的处理ClientDeregisterServiceEvent,同样的搜索对应的handler的相关逻辑

image-20260121172758504

剩下的部分也就是对于内存注册表,订阅表等的一些remove操作以及同步集群了

总结-Nacos2.x注册中心部分

  1. 对于临时实例,会采用RPC的方式进行通讯

  2. 内存注册表的结构变化。由原本的嵌套式Map转化为了平铺式Map,结构更加i清晰

  3. 客户端查询微服务实例列表的时候,调用的是客户端订阅的请求,在服务端会有订阅表,当我们被订阅的服务发生了变动,会来通知订阅者。

  4. 可以明显感觉到,2.0中的事件发布操作明显更多了

编程 Java 项目