003-Nacos 2.1.x 注册实例源码分析

news/2024/7/2 21:33:55 标签: java, 分布式, spring boot

目录

  • Nacos 2.1.X
    • 注册实例
      • 入口
      • 接口流程
      • Client 注册 事件处理
    • 服务订阅
      • 入口

Nacos 2.1.X

在这里插入图片描述

注册实例

入口

java">com.alibaba.nacos.naming.remote.rpc.handler.InstanceRequestHandler#handle

Service service = Service.newService(request.getNamespace(), request.getGroupName(), request.getServiceName(), true);
switch (request.getType()) {
    case NamingRemoteConstants.REGISTER_INSTANCE:
        return registerInstance(service, request, meta);
}

接口流程

java">registerInstance(Service service, Instance instance, String clientId):

clientOperationService.registerInstance(service, request.getInstance(), meta.getConnectionId());

NotifyCenter.publishEvent(new RegisterInstanceTraceEvent());
java">registerInstance(Service service, Instance instance, String clientId):

//获取一个服务实例
//如果 singletonRepository 没有service 则发布 MetadataEvent.ServiceMetadataEvent 并设置到Map中
//ConcurrentHashMap<Service, Service> singletonRepository
//ConcurrentHashMap<String, Set<Service>> namespaceSingletonMaps
Service singleton = ServiceManager.getInstance().getSingleton(service);

if (!singleton.isEphemeral()) {
	//2.1.x 开始 临时实例走 gRpc 持久实例还是走http
	//也就是只优化了常用的临时实例 不常用的就没有优化
	throw new NacosRuntimeException();
}
//根据 clientId 获取一个 client
//这个对象就是对应一个连接端信息 一个连接就有一个 clientId 对应有一个 client
//ConcurrentMap<String, IpPortBasedClient> clients
Client client = clientManager.getClient(clientId);
InstancePublishInfo instanceInfo = getPublishInfo(instance);
//维护 ConcurrentHashMap<Service, InstancePublishInfo> publishers
client.addServiceInstance(singleton, instanceInfo);
client.setLastUpdatedTime();
client.recalculateRevision();
//给 client 赋值

NotifyCenter.publishEvent(new ClientOperationEvent.ClientRegisterServiceEvent();
NotifyCenter.publishEvent(new MetadataEvent.InstanceMetadataEvent();

这个主流程可以看出来,其实就做了2件事就是

  1. 组装各种对象 放入各种 Map 中
  2. 发布各种事件

我们看下发布的事件:
RegisterInstanceTraceEvent
ServiceMetadataEvent
ClientRegisterServiceEvent
InstanceMetadataEvent

如果要分析注册 那么应该看 ClientRegisterServiceEvent 事件处理

Client 注册 事件处理

java">com.alibaba.nacos.naming.core.v2.index.ClientServiceIndexesManager#handleClientOperation

//ConcurrentMap<Service, Set<String>> publisherIndexes : Set<String> By service Map
publisherIndexes.computeIfAbsent(service, key -> new ConcurrentHashSet<>());
publisherIndexes.get(service).add(clientId);
//这里发布了服务变更事件 也就是说注册已经完成了 也就是说注册其实就是写入这个Map
NotifyCenter.publishEvent(new ServiceEvent.ServiceChangedEvent(service, true));

那这些 Map 到底有什么用呢?可以梳理一下查询服务逻辑看一下是怎么关联的

服务订阅

入口

java">com.alibaba.nacos.naming.remote.rpc.handler.SubscribeServiceRequestHandler#handle

Service service = Service.newService(namespaceId, groupName, serviceName, true);
Subscriber subscriber = new Subscriber(meta.getClientIp(), meta.getClientVersion(), app, meta.getClientIp(),
	namespaceId, groupedServiceName, 0, request.getClusters());

// 这一句比较关键 下边详细分析
ServiceInfo serviceInfo = ServiceUtil.selectInstancesWithHealthyProtection(serviceStorage.getData(service),
	metadataManager.getServiceMetadata(service).orElse(null), subscriber.getCluster(), false,
    true, subscriber.getIp());
if (request.isSubscribe()) {
    clientOperationService.subscribeService(service, subscriber, meta.getConnectionId());
    NotifyCenter.publishEvent(new SubscribeServiceTraceEvent(System.currentTimeMillis(),
            meta.getClientIp(), service.getNamespace(), service.getGroup(), service.getName()));
}

//从这里看一看出服务列表就是在 serviceInfo 中
return new SubscribeServiceResponse(ResponseCode.SUCCESS.getCode(), "success", serviceInfo);
java">ServiceUtil.selectInstancesWithHealthyProtection(serviceStorage.getData(service),
	metadataManager.getServiceMetadata(service).orElse(null), subscriber.getCluster(), false,
    true, subscriber.getIp()):

serviceStorage.getData(service):
// 看下缓存有不 没有就创建一个 
return serviceDataIndexes.containsKey(service) ? serviceDataIndexes.get(service) : getPushData(service);

getPushData(service):

ServiceInfo result = emptyServiceInfo(service);
//ConcurrentHashMap<Service, Service> singletonRepository 这个有了
Service singleton = ServiceManager.getInstance().getSingleton(service);
//根据 Service 获取所有 Instances
result.setHosts(getAllInstancesFromIndex(singleton));
serviceDataIndexes.put(singleton, result);
return result;
java">List<Instance> getAllInstancesFromIndex(Service service):

//ConcurrentMap<Service, Set<String>> publisherIndexes 根据service获取 Set<clientId>
for (String each : serviceIndexesManager.getAllClientsRegisteredService(service)) {
	//ConcurrentMap<String, IpPortBasedClient> clients
	//ConcurrentHashMap<Service, InstancePublishInfo> publishers
	Optional<InstancePublishInfo> instancePublishInfo = getInstanceInfo(each, service);
	if (instancePublishInfo.isPresent()) {
        InstancePublishInfo publishInfo = instancePublishInfo.get();
        if (publishInfo instanceof BatchInstancePublishInfo) {
            BatchInstancePublishInfo batchInstancePublishInfo = (BatchInstancePublishInfo) publishInfo;
            List<Instance> batchInstance = parseBatchInstance(service, batchInstancePublishInfo, clusters);
            result.addAll(batchInstance);
        } else {
            Instance instance = parseInstance(service, instancePublishInfo.get());
            result.add(instance);
            clusters.add(instance.getClusterName());
        }
    }
}
//维护 ConcurrentMap<Service, Set<String>> serviceClusterIndex
serviceClusterIndex.put(service, clusters);
return new LinkedList<>(result);

http://www.niftyadmin.cn/n/4957109.html

相关文章

【LeetCode-中等题】128. 最长连续序列

题目 题解一&#xff1a;HeshSet枚举 思路&#xff1a;先对数组进行set去重&#xff0c;核心就是&#xff0c;先找出临界值&#xff08;假设以最小临界为例&#xff0c;那么这个临界值自己就是最小值&#xff0c;&#xff09;&#xff0c;以临界值不断做加1操作&#xff0c;看…

T599聚合物电容器:在汽车应用中提供更长的使用寿命的解决方案

自从电子技术被引入汽车工业以来&#xff0c;汽车的技术含量一直在提升。诸多技术被应用在汽车上&#xff0c;使汽车的形象更接近于轮子上的超级计算机。更多传感器、更强大的计算能力和电力被装载到汽车上&#xff0c;汽车应用中的电子产品数量正在迅速增长。随着电动汽车和自…

手机技巧:分享五个非常实用的生活类APP

目录 1、我的桌面iScreen-桌面美化神器 2.Just Rain-创意听雨声APP 3.得言-美文句子神器 4、微手帐 5、暗盒-隐私保护神器 今天给大家整理5个非常实用的实用APP软件&#xff0c;感兴趣的朋友可以下载试试&#xff01; 1、我的桌面iScreen-桌面美化神器 我的桌面iScreen是一…

派森 #P125. 寻找反素数

描述 反素数&#xff0c;英文称作 emirp&#xff08;prime&#xff08;素数&#xff09;的左右颠倒拼写&#xff09;&#xff0c;是素数的一种。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭…

【MySQL系列】MySQL内置函数的学习

「前言」文章内容大致是对MySQL内置函数的学习。 「归属专栏」MySQL 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、MySQL的日期函数二、MySQL的字符串函数三、MySQL的数学函数四、 其它函数 一、MySQL的日期函数 常见的日期函数如下&#xff1a; 函数名称描述current…

CentOS 8.5修改安装包镜像源

1 备份原配置 cd /etc/yum.repos.d mkdir backup mv *.repo backup/2 下载镜像源 2.1 使用wget下载 wget http://mirrors.aliyun.com/repo/Centos-8.repo2.2 使用curl下载 我是安装的最小版本的系统&#xff0c;默认只有curl curl使用方法&#xff1a;https://www.ruanyife…

Gitbook超详细使用教程,搭建属于你自己的博客!

文章目录 简介与github同步1.创建space2.安装github插件3.同步github4.生成space的url 博客搭建指南1.自定义域名2.发表博客内容3.设置域名默认页面4.界面设置注意事项 End 简介 Gitbook 是一个平台&#xff0c;允许用户创建和分享内容丰富的在线书籍。它有一个用户友好的界面…

永久设置pip指定国内镜像源(windows内)

1.首先列出国内四个镜像源网站&#xff1a; 一、清华源 https://pypi.tuna.tsinghua.edu.cn/simple/ 二、阿里源 https://mirrors.aliyun.com/pypi/simple 三、中科大源 https://pypi.mirrors.ustc.edu.cn/simple/ 四、豆瓣源 http://pypi.douban.com/simple/ 2.一般下载所需要…