5 nacos注册中心之服务注册服务端的处理

举报
周杰伦本人 发表于 2022/05/11 19:36:03 2022/05/11
【摘要】 5 nacos注册中心之服务注册服务端的处理这篇文章是基于nacos 1.1.4 的源码进行分析的Nacos提供了SDK和Open API的形式实现服务注册,两种方式本质都是一样的,SDK方式提供了一种访问的封装,底层是基于HTTP 协议完成请求的,所有我们直接基于Open API请求方式分析一下服务端的服务注册原理。/nacos/v1/ns/instance服务注册对外提供的服务接口请求...

5 nacos注册中心之服务注册服务端的处理

这篇文章是基于nacos 1.1.4 的源码进行分析的

Nacos提供了SDK和Open API的形式实现服务注册,两种方式本质都是一样的,SDK方式提供了一种访问的封装,底层是基于HTTP 协议完成请求的,所有我们直接基于Open API请求方式分析一下服务端的服务注册原理。

/nacos/v1/ns/instance

服务注册对外提供的服务接口请求地址为nacos/v1/ns/instance,实现代码为nacos-naming下的InstanceController类:

@RestController
@RequestMapping(UtilsAndCommons.NACOS_NAMING_CONTEXT + "/instance")
public class InstanceController {
    @CanDistro
    @PostMapping
    public String register(HttpServletRequest request) throws Exception {

        String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
        String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);

        serviceManager.registerInstance(namespaceId, serviceName, parseInstance(request));
        return "ok";
    }
}

调用registerInstance方法:

public void registerInstance(String namespaceId, String serviceName, Instance instance) throws NacosException {

    createEmptyService(namespaceId, serviceName, instance.isEphemeral());

    Service service = getService(namespaceId, serviceName);

    if (service == null) {
        throw new NacosException(NacosException.INVALID_PARAM,
            "service not found, namespace: " + namespaceId + ", service: " + serviceName);
    }

    addInstance(namespaceId, serviceName, instance.isEphemeral(), instance);
}
  1. 创建一个空服务,实际是初始化serviceMap
  2. getService:从serviceMap中根据namespaceId和serviceName得到服务对象
  3. 调用addInstance添加服务实例。

createEmptyService

createEmptyService用来创建空服务,调用createServiceIfAbsent

public void createServiceIfAbsent(String namespaceId, String serviceName, boolean local, Cluster cluster) throws NacosException {
    Service service = getService(namespaceId, serviceName);
    if (service == null) {

        Loggers.SRV_LOG.info("creating empty service {}:{}", namespaceId, serviceName);
        service = new Service();
        service.setName(serviceName);
        service.setNamespaceId(namespaceId);
        service.setGroupName(NamingUtils.getGroupName(serviceName));
        // now validate the service. if failed, exception will be thrown
        service.setLastModifiedMillis(System.currentTimeMillis());
        service.recalculateChecksum();
        if (cluster != null) {
            cluster.setService(service);
            service.getClusterMap().put(cluster.getName(), cluster);
        }
        service.validate();

        putServiceAndInit(service);
        if (!local) {
            addOrReplaceService(service);
        }
    }
}
  1. 根据namespaceId和serviceName从缓存中获取Service实例
  2. 如果没有,创建并调用putServiceAndInit()保存到缓存中。

putServiceAndInit方法:

private void putServiceAndInit(Service service) throws NacosException {
    putService(service);
    service.init();
    consistencyService.listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), true), service);
    consistencyService.listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), false), service);
    Loggers.SRV_LOG.info("[NEW-SERVICE] {}", service.toJSON());
}
  1. 通过putService方法将服务缓存到内存
  2. service.init();建立心跳检测机制,通过定时任务不断检测当前服务下所有实例最后发送心跳包的时间。如果超时,则设置healthy为false表示服务不健康,并发送服务变更事件。
  3. consistencyService.listen实现数据一致性的监听

总结:

Nacos提供了SDK和Open API的形式实现服务注册,两种方式本质都是一样的

服务注册对外提供的服务接口请求地址为nacos/v1/ns/instance

服务注册过程:

  1. nacos客户端通过Open API的形式发送服务注册请求
  2. 服务端收到请求:
    • 构建一个Service对象保存到Map集合中
    • 使用定时任务对当前服务下的所有实例建立心跳检测机制。
    • 基于数据一致性协议将服务数据进行同步。
      nacos的服务注册对我们很重要,我们要理解其中的原理和注册流程,然后分析看源码,从而更好的理解nacos是怎么实现服务的注册的,这样我们才能理解透彻nacos的运作机制,以后在我们工作中遇到什么问题,我们能够及时排查,快速定位,这样我们才能在工作和学习中更好的提高效率完成任务。
      你觉得这篇文章不错的话,请留言点赞评论~~
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。