Nacos服务下线主要包含两部分:
- 服务主动下线。
- 服务异常下线。
服务下线整体流程,如图所示:
其中:
- 浅红色部分:服务主动下线处理流程。
- 浅蓝色部分:服务异常下线处理流程。
服务主动下线处理流程:
- 1)客户端调用NacosNamingService#deregisterInstance方法发起服务下线请求,判断客户端实例类型,如果为临时实例,则从服务心跳集合中移除该服务对应的心跳信息。
- 2)组装注销服务请求参数,并向服务端发送注册服务请求。
- 3)服务端接收注销服务请求,调用InstanceController#register方法,从注册表中删除需要注销的服务实例。
- 4)发布服务变更事件。
服务异常下线处理流程:
- 1)服务端以5秒/次的频率进行心跳检测。
- 2)判断服务实例最后一次心跳时间距离当前时间是否超过心跳检测超时时长(默认为15s),超过心跳检测超时时长,则设置服务实例的健康状态为false,并发布一个服务变更事件和心跳超时事件。
- 4)判断服务实例最后一次心跳时间距离当前时间是否超过删除实例设定的超时时长(默认为30s),超过删除实例设定的超时时长,则将该实例从实例列表中移除。
- 5)继续以5秒/次的频率检测服务心跳。
删除服务接口与注册服务接口是同一个接口(即:/nacos/v1/ns/instance):
- 注册服务请求类型为:POST。
- 删除服务请求类型为:DELETE。
注册服务接口详细信息请移步->「一文搞懂」Nacos服务注册实现原理。
客户端发送服务下线请求实现原理
客户端发送服务下线请求流程,如图所示:
处理流程:
- 1)客户端调用NacosNamingService#deregisterInstance方法发起服务下线请求,判断客户端实例类型,如果为临时实例,则从服务心跳集合中移除该服务对应的心跳信息。
- 2)组装注销服务请求参数,并向服务端发送注册服务请求。
源码解析
服务主动下线时,服务主动调用NacosNamingService#deregisterInstance方法发起服务下线请求。
NacosNamingService#deregisterInstance方法主要做以下事情:
- 判断服务实例是否为临时实例,如果为临时实例,则从服务心跳集合中移除该服务对应的心跳信息。
- 向Nacos服务端发送注销服务实例请求。
源码如下:
// com.alibaba.nacos.client.naming.NacosNamingService#deregisterInstance
/**
* 注销服务
* @param serviceName 服务名
* @param groupName 分组名
* @param instance 服务实例
*/
@Override
public void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException {
// 判断服务实例是否为临时实例
if (instance.isEphemeral()) {
// 从服务心跳集合中移除该服务对应的心跳信息
beatReactor.removeBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), instance.getIp(),
instance.getPort());
}
// 向Nacos服务端发送注销服务实例请求
serverProxy.deregisterService(NamingUtils.getGroupedName(serviceName, groupName), instance);
}
BeatReactor#removeBeatInfo方法主要做以下事情:
- 从服务心跳集合中移除该服务对应的心跳信息。
源码如下:
// com.alibaba.nacos.client.naming.beat.BeatReactor#removeBeatInfo
public void removeBeatInfo(String serviceName, String ip, int port) {
NAMING_LOGGER.info("[BEAT] removing beat: {}:{}:{} from beat map.", serviceName, ip, port);
// 从服务心跳集合中移除该服务对应的心跳信息
BeatInfo beatInfo = dom2Beat.remove(buildKey(serviceName, ip, port));
if (beatInfo == null) {
return;
}
// 设置停止心跳标识为true
beatInfo.setStopped(true);
// 记录心跳统计信息
MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
}
NamingProxy#deregisterService方法主要做以下事情:
- 组装请求参数。
- 调用删除服务接口(/nacos/v1/ns/instance)向Nacos服务端发送注销服务请求,注意:请求类型为DELETE。
源码如下:
// com.alibaba.nacos.client.naming.net.NamingProxy#deregisterService
public void deregisterService(String serviceName, Instance instance) throws NacosException {
// ...打印日志
// 组装请求参数
final Map<String, String> params = new HashMap<String, String>(8);
params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.Cluster_NAME, instance.getClusterName());
params.put("ip", instance.getIp());
params.put("port", String.valueOf(instance.getPort()));
params.put("ephemeral", String.valueOf(instance.isEphemeral()));
// 调用删除服务接口(/nacos/v1/ns/instance)向Nacos服务端发送注销服务请求
// 注意:请求类型为DELETE
reqApi(UtilAndComs.nacosUrlInstance, params, HttpMethod.DELETE);
}
服务端处理服务下线请求
实现原理
Nacos服务端接收删除服务请求后,调用删除服务接口(即:注册服务接口,请求类型为DELETE)对应的处理方法InstanceController#register进行处理(即:从注册表中删除需要注销的服务实例)。
服务端处理服务下线请求实现原理请移步->「一文搞懂」Nacos服务注册实现原理。
源码解析
服务端处理服务下线请求源码解析请移步->「一发入魂」Nacos服务注册源码解析。
服务异常下线实现原理
服务异常下线通过Nacos健康检查机制实现,服务实例注册成功后,会以5秒/次的频率上报自身心跳信息。
Nacos服务端以5秒/次的频率进行心跳检测,检测逻辑:
- 判断服务实例最后一次心跳时间距离当前时间是否超过心跳检测超时时长(默认为15s),超过心跳检测超时时长,则设置服务实例的健康状态为false,并发布一个服务变更事件和心跳超时事件。
- 判断服务实例最后一次心跳时间距离当前时间是否超过删除实例设定的超时时长(默认为30s),超过删除实例设定的超时时长,则将该实例从实例列表中移除。
Nacos健康检查机制请移步->「一文搞懂」Nacos健康检查机制。
源码解析
Nacos健康检查源码解析请移步->「超级详细」Nacos健康检查源码解析。
【阅读推荐】
更多精彩内容,如:
- Redis系列
- 数据结构与算法系列
- Nacos系列
- MySQL系列
- JVM系列
- Kafka系列
请移步【南秋同学】个人主页进行查阅。内容持续更新中......
【作者简介】
一枚热爱技术和生活的老贝比,专注于Java领域,关注【南秋同学】带你一起学习成长~
,