Nacos源码系列—服务端那些事儿

前言

在上节课中,我们讲解了客户端注册服务的大体流程,客户端在注册服务的时候调用的是 NamingService.registerInstance 来完成实例的注册,在最后呢我们知道服务注册是通过 nacos/v1/ns/instance 接口来完成注册的,我们今天来讲解服务端的注册,首先就从这个接口地址开始,来看具体服务端都做了哪些事情

服务注册

Nacos源码系列—服务端那些事儿_第1张图片

上面是我们从官网中找到的Nacos架构图,从这个图中我们大体可以得出我们要找的接口应该是在NamingService这个服务中,同时我们在项目结构中也可以看到naming这个模块,naming就是实现服务注册的,我们都知道请求路径都是通过controller来进行处理的,而在其中我们可以看到一个InstanceController的这么一个类,那么注册实例肯定会和它有关。可以看到InstanceController类的请求路由即是我们POST请求的路由的部分,如下:

Nacos源码系列—服务端那些事儿_第2张图片

所以,我们就从开始研究接收请求处理服务注册的源码,我们找到通过RestFul API接口,请求类型为Post,的方法,符合条件的只有InstanceController.register方法,这个方法用来接收用户的请求,并且把收到的信息进行解析,装换成实例信息,然后通过getInstanceOperator().registerInstance进行调用,这个方法也是服务注册的核心

    @CanDistro
    @PostMapping
    @Secured(action = ActionTypes.WRITE)
    public String register(HttpServletRequest request) throws Exception {
        //从 request信息中获取namespaceId,如果没有默认为public
        final String namespaceId = WebUtils
                .optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
        //获取服务名称 格式:“group@@serviceName”
        final String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
        NamingUtils.checkServiceNameFormat(serviceName);
        //将request参数还原成instance实例
        final Instance instance = HttpRequestInstanceBuilder.newBuilder()
                .setDefaultInstanceEphemeral(switchDomain.isDefaultInstanceEphemeral()).setRequest(request).build();
        //【核心】注册服务实例
        getInstanceOperator().registerInstance(namespaceId, serviceName, instance);
        return "ok";
    }

我们先来看一下下面这个核心方法

getInstanceOperator().registerInstance(namespaceId, serviceName, instance);

getInstanceOperator() 这个判断是否走Grpc协议,默认走Grpc,所以我们使用的是instanceServiceV2这个实例对象

  private InstanceOperator getInstanceOperator() {
        return upgradeJudgement.isUseGrpcFeatures() ? instanceServiceV2 : instanceServiceV1;
    }

instanceServiceV2就是InstanceOperatorClientImpl,方法所以我们需要进入的是下面这个实例的处理类

Nacos源码系列—服务端那些事儿_第3张图片

具体方法如下所示:

    @Override
    public void registerInstance(String namespaceId, String serviceName, Instance instance) {
        //判断是否为临时客户端
        boolean ephemeral = instance.isEphemeral();
        //获取客户端ID
        String clientId = IpPortBasedClient.getClientId(instance.toInetAddr(), ephemeral);
        //通过客户端ID创建客户端连接
        createIpPortClientIfAbsent(clientId);
        //获取服务信息
        Service service = getService(namespaceId, serviceName, ephemeral);
        //注册服务
        clientOperationService.registerInstance(service, instance, clientId);
    }

你可能感兴趣的:(Java技术文,java,开发语言)