Nacos注册中心8-Server端(处理注册请求)

0. 环境

  • nacos版本:1.4.1
  • Spring Cloud : 2020.0.2
  • Spring Boot :2.4.4
  • Spring Cloud alibaba: 2.2.5.RELEASE

测试代码:github.com/hsfxuebao/s…

1. InstanceController#register

nacos注册中心功能是在naming这个子项目下面的,是个springboot项目,然后我们直接找controller就可以了,找到这个InstanceController,第一个方法就是服务注册方法(register方法):

@CanDistro
@PostMapping
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public String register(HttpServletRequest request) throws Exception {
    // 从请求中获取指定属性值
    final String namespaceId = WebUtils
            .optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
    // 从请求中获取指定属性值
    final String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
    // 检测serviceName是否合法
    NamingUtils.checkServiceNameFormat(serviceName);

    // 通过请求参数组装出instance
    final Instance instance = parseInstance(request);

    // todo 将instance写到注册表
    serviceManager.registerInstance(namespaceId, serviceName, instance);
    return "ok";
}
复制代码

先是解析出来instance,就是根据client发送的那堆参数解析出来的。接着就是调用serviceManager组件进行实例注册,这个serviceManager 组件在注册中心是个核心组件(服务注册,下线,获取服务列表等),都是找这个组件的。

2. ServiceManager#registerInstance

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

    // 创建 空service
    // 第三个参数 true表示临时实例
    createEmptyService(namespaceId, serviceName, instance.isEphemeral());

    // 从注册表获取到service
    Service service = getService(namespaceId, serviceName);
    // 这里指定不能为null
    if (service == null) {
        throw new NacosException(NacosException.INVALID_PARAM,
                "service not found, namespace: " + namespaceId + ", service: " + serviceName);
    }
    // todo 将instance写入到service,即写入到了注册表
    addInstance(namespaceId, serviceName, instance.isEphemeral(), instance);
}
复制代码

这几个步骤都很重要,我们挨个看看,createEmptyService这个方法就是当service 不存在的时候,创建一个空的serivce,这service你可以理解为服务,其实就是服务的意思,看下这个方法

2.1 ServiceManager#createEmptyService

public void createEmptyService(String namespaceId, String serviceName, boolean local) throws NacosException {
    // local为true,表示当前实例为临时实例
    createServiceIfAbsent(namespaceId, serviceName, local, null);
}

public void createServiceIfAbsent(String namespaceId, String serviceName, boolean local, Cluster cluster)
        throws NacosException {
    // 从注册表中获取service
    Service service = getService(namespaceId, serviceName);
    // 若当前注册instance是其提供服务的第一个实例,则注册表中是没有该service的,
    // 此时会创建一个service实例
    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());
        // todo 重新计算校验和
        service.recalculateChecksum();
        if (cluster != null) {
            // cluster与service建立联系
            cluster.setService(service);
            service.getClusterMap().put(cluster.getName(), cluster);
        }
        service.validate();
        // todo 将service写入到注册表
        putServiceAndInit(service);
        // 对持久实例的操作
        if (!local) {
            addOrReplaceService(service);
        }
    }
}
复制代码

先是根据namespace与serviceName 获取service ,如果没有的话,就创建,最开始的时候,肯定是没有的,然后就会创建一个service,看下这个getService 方法:

public Service getService(String namespaceId, String serviceName) {
    if (serviceMap.get(namespaceId) == null) {
        return null;
    }
    return chooseServiceMap(namespaceId).get(serviceName);
}
复制代码

说白了其实就是去serviceMap 这个成员中获取,对应关系看下面这个注释就可以。

// namespace   ---》 ser
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值