网站首页 > 博客文章 正文
本章内容
服务注册表
服务注册表的主要作用是存储服务注册信息。
服务注册表结构,如图所示:
服务注册表:
// com.alibaba.nacos.naming.core.ServiceManager#serviceMap
Map<String, Map<String, Service>> serviceMap = new ConcurrentHashMap<>();
其中:
- 外层map:
- key:命名空间(namespace),主要用于环境隔离,如:public、生产环境、测试环境等。
- value:命名空间下的所有服务信息,是一个map结构。
- 内层map:
- key:组名@@服务名称,如:DEFAULT_GROUP@@order-server ,表示分组维度下的服务信息。
- value:服务信息,是一个Service实例。
- 服务信息:
- key:服务集群名称,如:DEFAULT。
- value:服务集群信息。一个服务集群中可能包含多个服务实例,每个服务实例会包括两个Set结构,用于存储服务对应的临时实例和持久实例。
Service实例:
// com.alibaba.nacos.naming.core.Service#clusterMap
private Map<String, Cluster> clusterMap = new HashMap<>();
Cluster实例:
// com.alibaba.nacos.naming.core.Cluster#persistentInstances
@JsonIgnore
private Set<Instance> persistentInstances = new HashSet<>();
// com.alibaba.nacos.naming.core.Cluster#ephemeralInstances
@JsonIgnore
private Set<Instance> ephemeralInstances = new HashSet<>();
Instance实例:包含InstanceId、IP、Port、健康状态、权重等信息。
Instance示例:
- instanceId:192.168.31.106#8081#DEFAULT#DEFAULT_GROUP@@order-server。
- ip:192.168.31.106。
- port:8081。
- healthy:true。
- weight:1.0。
- ephemeral:true。
服务注册流程
服务(Nacos客户端)启动时,通过调用Nacos服务端服务注册接口将服务信息保存到服务注册表中,完成服务注册。
服务注册接口
请求协议:HTTP(2.x版本新增gRPC)
请求类型:POST
请求路径:/nacos/v1/ns/instance
请求参数
响应编码
客户端
服务(Nacos客户端)启动时,通过监听服务初始化完成事件开启服务注册流程,并调用Nacos服务端提供的服务注册接口完成服务注册。
服务注册流程
如图所示:
处理步骤:
- 1)服务启动时,Spring容器初始化完成后发布初始化完成事件,AbstractAutoServiceRegistration实现了ApplicationListener接口的onApplicationEvent()方法,因此,会触发AbstractAutoServiceRegistration.onApplicationEvent()方法,通过该方法中调用bind()方法开启服务注册流程。
- 2)创建服务实例封装服务注册信息。
- 3)如果实例类型为临时实例,则向Nacos服务端定时(5秒/次)发送心跳请求。
- 4)组装请求参数,调用服务注册接口向Nacos服务端注册服务实例。
服务端
收到客户端注册请求后,Nacos服务端通过服务注册接口对应的处理方法将服务注册到服务注册表中。
Nacos服务端启动类为nacos-console模块中的com.alibaba.nacos.Nacos类,而在nacos-console模块中引入了nacos-naming模块,nacos-naming模块的controllers包下包含服务注册、服务发现、服务续约等多种类型的控制处理器,其中服务注册对应的控制处理器为:InstanceController。
服务注册流程
如图所示:
图中:
- 红色部分表示获取服务最新的实例列表。
- 黄色部分表示更新服务最新的实例信息到注册表中(即:服务注册)。
- 蓝色部分表示通过Distro协议将服务信息同步给集群中的其他Nacos节点。
处理步骤:
- 1)Nacos服务端接收客户端注册请求,根据请求参数获取命名空间ID、服务名,并生成对应的服务实例。
- 2)创建并初始化Service,将其添加到注册表中(针对第一次注册服务)。
- 3)根据namespaceId,、serviceName从注册表中获取对应的服务信息。
- 4)根据namespaceId、serviceName、实例类型(临时、持久)生成服务唯一标识。
- 5)获取最新的实例列表(旧实例列表+待注册实例列表)。
- 6)根据服务唯一标识前缀判断服务实例类型(临时、持久)选择不同协议进行服务注册与同步(以临时实例为例)。
- 7)服务注册:
- 将服务对应的实例列表信息封装成Datum加入到DataStore(数据集)中。
- 将服务唯一标识、操作类型封装成一个Task任务加入到DistroConsistencyServiceImpl.Notifier的任务队列中。
- 线程池中的异步线程Notifier通过死循环的方式从任务队列中取出任务进行处理:
- 更新操作:
- 更新服务对应的实例列表信息(即:替换旧实例+添加新实例)。
- 更新服务MD5校验码。
- 删除操作:
- 更新服务对应的实例列表信息(即:从服务实例列表中移除实例)。
- 8)服务信息同步(遍历集群中除自己以外的其他Nacos节点):
- 将服务信息、资源类型以及目标节点封装成DistroKey。
- 将DistroKey、操作类型封装成延时任务DelayTask添加到Nacos延时任务执行器的任务集合中。
- 定时任务通过线程池中的异步处理线程ProcessRunnable从任务集合中取出任务进行数据同步处理。
- 任务处理失败,则将任务重新加入到任务集合中进行重试。
服务注册常见问题
1)Nacos服务端如何支持高并发注册?
采用队列+异步线程的方式进行服务注册,避免客户端同步将注册信息同步写入注册表。
2)Nacos服务端如何保证并发安全性?
向注册中心注册服务实例时,会对Service对象添加同步锁,保证服务实例信息并发写入的安全性。
3)Nacos服务端如何避免并发读写冲突?
利用CopyOnWrite思想,更新(新增、修改、删除等)服务信息时,先拷贝现有服务信息,生成服务信息副本,在服务信息副本中更新服务信息,更新完成后直接替换现有服务信息,完成服务信息更新。
【阅读推荐】
更多精彩内容(如:Redis、数据结构与算法、Kafka等)请移步【南秋同学】个人主页进行查阅。
【作者简介】
一枚热爱技术和生活的老贝比,专注于Java领域,关注【南秋同学】带你一起学习成长~
猜你喜欢
- 2024-10-01 微服务学习笔记(微服务怎么学)
- 2024-10-01 干货:SpringBoot集成Nacos,填坑篇
- 2024-10-01 记一次把Nacos做成服务并开机启动
- 2024-10-01 Nacos 配置中心与注册中心(nacos配置中心连接超时)
- 2024-10-01 小白入门必知必会-Nacos单机安装(nacos入门教程)
- 2024-10-01 windows系统 安装nacos服务注册与发现中心
- 2024-10-01 网络环境问题导致的nacos集群故障
- 2024-10-01 分布式服务限流降级熔断解决方案Nacos之Dashboard界面配置含义
- 2024-10-01 Nacos你真的理解了吗(nacos百科)
- 2024-10-01 java微服务环境配置——注册中心 配置中心Nacos
你 发表评论:
欢迎- 367℃用AI Agent治理微服务的复杂性问题|QCon
- 358℃初次使用IntelliJ IDEA新建Maven项目
- 357℃手把手教程「JavaWeb」优雅的SpringMvc+Mybatis整合之路
- 351℃Maven技术方案最全手册(mavena)
- 348℃安利Touch Bar 专属应用,让闲置的Touch Bar活跃起来!
- 346℃InfoQ 2024 年趋势报告:架构篇(infoq+2024+年趋势报告:架构篇分析)
- 345℃IntelliJ IDEA 2018版本和2022版本创建 Maven 项目对比
- 342℃从头搭建 IntelliJ IDEA 环境(intellij idea建包)
- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)