nacos 基于 2.2.4 版本
这里的 client
是指 nacos SDK
,也就是模块 nacos-client
.
注销实例的主流程
源码位置: com.alibaba.nacos.client.naming.NacosNamingService#deregisterInstance
1
2
3
4
5
6
| // 入口类: NacosNamingService
@Override
public void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException {
// clientProxy 的实现类为 NamingClientProxyDelegate
clientProxy.deregisterService(serviceName, groupName, instance);
}
|
源码位置: com.alibaba.nacos.client.naming.remote.NamingClientProxyDelegate#deregisterService
1
2
3
4
5
6
7
8
9
10
11
12
| // NamingClientProxyDelegate 注销实例
// 临时实例, grpcClientProxy
// 持久化实例, httpClientProxy
@Override
public void deregisterService(String serviceName, String groupName, Instance instance) throws NacosException {
getExecuteClientProxy(instance).deregisterService(serviceName, groupName, instance);
}
// 根据是否为临时实例来获取 clientProxy
private NamingClientProxy getExecuteClientProxy(Instance instance) {
return instance.isEphemeral() ? grpcClientProxy : httpClientProxy;
}
|
注销临时实例
源码位置: com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy#deregisterService
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| @Override
public void deregisterService(String serviceName, String groupName, Instance instance) throws NacosException {
NAMING_LOGGER
.info("[DEREGISTER-SERVICE] {} deregistering service {} with instance: {}", namespaceId, serviceName,
instance);
// 标记 instance 要注销,可以在 redoService 定时任务重试
redoService.instanceDeregister(serviceName, groupName);
// 注销实例
doDeregisterService(serviceName, groupName, instance);
}
// redoService.instanceDeregister
public void instanceDeregister(String serviceName, String groupName) {
String key = NamingUtils.getGroupedName(serviceName, groupName);
synchronized (registeredInstances) {
InstanceRedoData redoData = registeredInstances.get(key);
if (null != redoData) {
// 设置注销中
redoData.setUnregistering(true);
// 设置最终状态
redoData.setExpectedRegistered(false);
}
}
}
// 注销实例
public void doDeregisterService(String serviceName, String groupName, Instance instance) throws NacosException {
InstanceRequest request = new InstanceRequest(namespaceId, serviceName, groupName,
NamingRemoteConstants.DE_REGISTER_INSTANCE, instance);
// 发送 InstanceRequest 请求,会被 InstanceRequestHandler 处理
requestToServer(request, Response.class);
// 标记 instance 已经注销
redoService.instanceDeregistered(serviceName, groupName);
}
|
源码位置: com.alibaba.nacos.naming.remote.rpc.handler.InstanceRequestHandler#handle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| // InstanceRequestHandler 处理请求
@Override
@Secured(action = ActionTypes.WRITE)
public InstanceResponse handle(InstanceRequest request, RequestMeta meta) throws NacosException {
Service service = Service
.newService(request.getNamespace(), request.getGroupName(), request.getServiceName(), true);
switch (request.getType()) {
...
case NamingRemoteConstants.DE_REGISTER_INSTANCE:
return deregisterInstance(service, request, meta);
}
}
// 注销实例
private InstanceResponse deregisterInstance(Service service, InstanceRequest request, RequestMeta meta) {
// 这个逻辑在【注销实例】章节中分析过了
clientOperationService.deregisterInstance(service, request.getInstance(), meta.getConnectionId());
NotifyCenter.publishEvent(new DeregisterInstanceTraceEvent(System.currentTimeMillis(),
meta.getClientIp(), true, DeregisterInstanceReason.REQUEST, service.getNamespace(),
service.getGroup(), service.getName(), request.getInstance().getIp(), request.getInstance().getPort()));
return new InstanceResponse(NamingRemoteConstants.DE_REGISTER_INSTANCE);
}
|
注销持久化实例
源码位置: com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy#deregisterService
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| // 发送一个 http 请求
@Override
public void deregisterService(String serviceName, String groupName, Instance instance) throws NacosException {
NAMING_LOGGER
.info("[DEREGISTER-SERVICE] {} deregistering service {} with instance: {}", namespaceId, serviceName,
instance);
if (instance.isEphemeral()) {
return;
}
final Map<String, String> params = new HashMap<>(16);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, NamingUtils.getGroupedName(serviceName, groupName));
params.put(CommonParams.CLUSTER_NAME, instance.getClusterName());
params.put(IP_PARAM, instance.getIp());
params.put(PORT_PARAM, String.valueOf(instance.getPort()));
params.put(EPHEMERAL_PARAM, String.valueOf(instance.isEphemeral()));
reqApi(UtilAndComs.nacosUrlInstance, params, HttpMethod.DELETE);
}
|
测试类
com.alibaba.nacos.test.naming.CPInstancesAPI_ITCase#registerInstance_ephemeral_true