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

news2024/11/16 1:36:57

目录

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

Nacos 2.1.X

在这里插入图片描述

注册实例

入口

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);
}

接口流程

registerInstance(Service service, Instance instance, String clientId):

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

NotifyCenter.publishEvent(new RegisterInstanceTraceEvent());
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 注册 事件处理

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 到底有什么用呢?可以梳理一下查询服务逻辑看一下是怎么关联的

服务订阅

入口

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);
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;
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.coloradmin.cn/o/909159.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络————IP数据报的首部各字段详解(很重要)

目录 1. IP数据报的介绍2. 首部的固定部分的各字段说明2.1 Version&#xff08;版本&#xff09;2.2 IHL&#xff08;首部长度&#xff09;2.3 Type of service&#xff08;区分服务&#xff09;2.4 Total Length&#xff08;总长度&#xff09;2.5 Identification&#xff08;…

企业级即时通讯协作和移动应用管理平台哪个品牌好?

在竞争激烈的商业环境下&#xff0c;高效的企业通讯和协作变得至关重要。WorkPlus作为领先的品牌&#xff0c;专注于提供企业级即时通讯协作和移动应用管理平台。本文将介绍WorkPlus如何成为企业实现协同工作、高效沟通和流程管理的理想解决方案。 一、全面协作加速工作流程&am…

二、1.保护模式

访问外部硬件有两个方式&#xff1a; 将某个外设的内存映射到一定范围的地址空间中&#xff0c; CPU 通过地址总线访问该内存区域时会落到外设 的内存中&#xff0c;这种映射让 CPU 访问外设的内存就如同访问主板上的物理内存一样外设是通过 IO 接口与 CPU 通信的&#xff0c;…

BDA初级分析——民宿投资决策影响因素分析

实战作业: 民宿投资决策影响因素分析如今&#xff0c;出门旅行住民宿已经不是一个新鲜话题&#xff0c;而且民宿品牌也是层出不穷.作为一名旅行服务业的数据分析师&#xff0c;我们以Airbnb北京的民宿为例&#xff0c;对其进行数据分析&#xff0c;探索什么类型的民宿价格更高?…

Eltima USB Network Gate 10.0 Crack

USB Network Gate -通过网络共享USB 设备 USB Network Gate (前身为以太网USB控制器USB) 轻松的通过网络(Internet/LAN/WAN)分享您的一个或者多个连接到您计算机的USB设备。 无论您身处异国还是近在隔壁办公室&#xff0c;您都可以轻松使用远程扫描仪、打印机、摄像头、调制解…

从零构建深度学习推理框架-9 再探Tensor类,算子输入输出的分配

再探Tensor类&#xff1a; 第二节中我们编写的Tensor类其实并不能满足我们的使用需要&#xff0c;我们将在这一节以代码阅读的方式来看看一个完全版本的Tensor应该具备怎样的要素&#xff0c;同时我们对Tensor类的分析来看看在C中一个设计好的类应该是怎么样的。 Tensor<fl…

K8s学习笔记3

Kubernetes功能&#xff1a; Kubernetes是一个轻便的可扩展的开源平台&#xff0c;用于管理容器化应用和服务。通过Kubernetes能够进行应用的自动化部署和扩缩容。在Kubernetes中&#xff0c;会将组成应用的容器组合成一个逻辑单元以更易管理和发现。Kubernetes积累了作为Goog…

打怪升级之从零开始的网络协议

序言 三个多月过去了&#xff0c;我又来写博客了&#xff0c;这一次从零开始学习网络协议。 总的来说&#xff0c;计算机网络很像现实生活中的快递网络&#xff0c;其最核心的目标&#xff0c;就是把一个包裹&#xff08;信息&#xff09;从A点发送到B点去。下面是一些共同的…

面试-快速学习计算机网络-UDP/TCP

1. OSI四层和七层映射 区别&#xff1a; 应用层&#xff0c;表示层&#xff0c;会话层合并为了应用层数据链路层和物理层合并为了网络接口层 2. TCP和UDP的区别&#xff1f; 总结&#xff1a; 1 . TCP 向上层提供面向连接的可靠服务 &#xff0c;UDP 向上层提供无连接不可靠服…

验证二叉搜索树

给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。 所有左子树和右子树自身必须也是二叉搜索树。 示例 1&#xff1a; 输…

8.21summary

计划部分完成&#xff0c;复习暂未完成

Linux环境下交叉编译环境安装、编译和运行

Win11主机上安装虚拟机&#xff0c;虚拟机内运行Ubuntu20.04&#xff0c;为了能够在本地电脑&#xff08;Win11&#xff09;上开发测试软件和算法&#xff0c;最终将编译好的可执行文件拷贝到Linux板上&#xff08;Rk3288上运行linux系统&#xff09;运行&#xff0c;因此需要安…

【QML】鼠标放在控件上颜色改变的效果实现

最近刚好要用到一个功能&#xff0c;在qml上实现鼠标放上去&#xff0c;控件的颜色改变&#xff0c;鼠标移走&#xff0c;控件颜色恢复。第一反应是这个功能非常简单&#xff0c;但是搞了一会儿都没实现&#xff0c;最后发现MouseArea其实提供了一个很简便的方法来提供使用&…

马蹄集 第九次oj赛

目录 MT2188单条件和 8421码 余3码 永恒之2 新十六进制 人脑计算机 二进制&#xff1f;不同&#xff01; 三进制计算机1 三进制计算机2 excel的烦恼 MT2188单条件和 号难度&#xff1a;黄金© 时间限制&#xff1a;1秒 巴占用内存&#xff1a;128M ★收藏△报错 “单…

MemSeg:一种差异和共性来检测图像表面缺陷的半监督方法

目录 1、摘要 2、Method 2.1 模拟异常样本 2.2 Memory Module 2.3 空间注意模块 2.4 多尺度特征融合模块 2.5 损失函数设置 2.6 Decoder模块 1、摘要 本文认为人为创建类内差异和保持类内共性可以帮助模型实现更好的缺陷检测能力&#xff0c;从而更好地区分非正常图像。如…

蓝蓝设计UI设计公司-界面设计与开发案例

天津航天中为项目 中国南方电网十二个软件交互优化和界面设计 图标设计 | 交互设计 | 界面设计 天津航天中为数据系统科技有限公司是航天503所控股的专业化公司&#xff0c;坐落于天津滨海新区航天技术产业园&#xff0c;是航天五院家入住天津未来科技城的军民融合型企业&…

el-tree组件图标的自定义

饿了么树形组件的图标自定义 默认样式: 可以看到el-tree组件左侧自带展开与收起图标,咱们可以把它隐藏:: .groupList {::v-deep .el-tree-node { .el-icon-caret-right {display: none;} } } 我的全部代码 <div class"groupList"><el…

韩顺平java集合

遍历集合方式: public static void main(String[] args) {List<Object> arrayList new ArrayList<>();arrayList.add(1);arrayList.add(3);arrayList.add(111);Iterator<Object> iterator arrayList.iterator();while (iterator.hasNext()){System.out.pri…

SpringBoot整合MongoDB(从安装到使用系统化展示)

SpringBoot整合MongoDB&#xff08;从安装到使用系统化展示&#xff09; MongoDB介绍 基础介绍 MongoDB是一种开源、面向文档的非关系型数据库管理系统&#xff08;NoSQL DBMS&#xff09;&#xff0c;它以其灵活性、可扩展性和强大的查询能力而闻名。MongoDB的设计理念是为了…

Linux journalctl命令详解(journalctl指令)

文章目录 Linux Journalctl命令详解1. Journalctl简介2. Journalctl基础使用3. 过滤日志条目4. 时间戳和日志轮转5. 高级应用6. journalctl --help指令文档英文中文 注意事项journal日志不会将程序输出的空行显示&#xff0c;日志会被压缩得满满当当。journal日志不会自动持久化…