nacos1.4.2

简介: nacos1.4.2

一、注册表结构

// com.alibaba.nacos.naming.core.ServiceManager
/**
 * Map(namespace, Map(group::serviceName, Service)).
 */
private final Map<String, Map<String, Service>> serviceMap = new ConcurrentHashMap<>();

 nacos1.X的注册表存于ServiceManager的一个ConcurrentHashMap中,key为命名空间,值又是一个ConcurrentHashMap,内层的ConcurrentHashMapkey为组名+服务名。值为Service服务对象。

 这个Service内部又存放了一个hashMap,key为集群名,值为集群对象Cluster。Cluster内部存放两个Set集合,一个存放持久化实例,一个存放临时实例。

// com.alibaba.nacos.naming.core.Service
// 这就是serve内部具体存放集群信息位置 
private Map<String, Cluster> clusterMap = new HashMap<>();
// com.alibaba.nacos.naming.core.Cluster   
// 持久化实例集合 
@JsonIgnore
private Set<Instance> persistentInstances = new HashSet<>();
    
// 临时实例集合
@JsonIgnore
private Set<Instance> ephemeralInstances = new HashSet<>();

  实例里面存放了IP、端口、集群名称等信息。

public Instance(String ip, int port) {
        this.setIp(ip);
        this.setPort(port);
        this.setClusterName(UtilsAndCommons.DEFAULT_CLUSTER_NAME);
    }
    
    public Instance(String ip, int port, String clusterName) {
        this.setIp(ip.trim());
        this.setPort(port);
        this.setClusterName(clusterName);
    }
    
    public Instance(String ip, int port, String clusterName, String tenant, String app) {
        this.setIp(ip.trim());
        this.setPort(port);
        this.setClusterName(clusterName);
        this.tenant = tenant;
        this.app = app;
    }

  以上所有结构组成了nacos1.X的实例注册表。

二、客户端服务注册核心源码

    客户端注册实例主要做两件事情,定时发送服务健康状态心跳、发送服务注册请求。

// 在服务启动的时候调用 注册实例
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
    
   NamingUtils.checkInstanceIsLegal(instance);
   String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
   
   //  如果是临时实例就服务端发心跳,内部是每隔5秒循环调用
   if (instance.isEphemeral()) {
       BeatInfo beatInfo = this.beatReactor.buildBeatInfo(groupedServiceName, instance);
       this.beatReactor.addBeatInfo(groupedServiceName, beatInfo);
   }
  
   //  注册实例
   this.serverProxy.registerService(groupedServiceName, groupName, instance);
}

定时发送服务健康状态心跳

    如果注册实例是临时实例,则建立心跳机制,原理是发起一个延时5秒的的异步任务向服务端发送健康状态,在这个任务的末尾又调用本身,实现每隔5秒的循环调用,发送心跳。

发送服务注册请求

三、服务端服务注册核心源码

    服务端是一个restful风格的HTTP接口

这个接口内会做以下几步;

 1.  如果service是第一次创建,则在初始化时创建一个针对该service 的健康检查定时任务,延迟5秒并且每隔5秒执行一次。这个定时任务遍历service下的所有实例,如果发现服务端超过15秒没收到客户端的心跳,则将该实例健康状态标记为false,如果超过30秒没发送心跳过来,则将该实例从注册中心剔除。

     如果使用了集群,则这一步只会有一个nacos节点来执行,具体是哪个节点是根据serviceName进行hash运算得到的。

 2. 将注册的实例信息放到一个ArrayBlockingQueue阻塞队列中,等待消费。所以这里是一个异常操作。

这个队列的消费逻辑是在nacos启动时开启了一个死循环。

 在实际的消费注册服务操作时,用到了写时复制的设计避免读写冲突。

实例权重范围是0.01-10000。

3. 每当服务端有服务信息变化时,比如有新的服务注册、服务修改、删除等,在处理队列异常消息时都会发布一个事件,通知相关客户端服务的变更信息,以提升客户端注册表信息更新的及时性。这是一个从服务端到客户端的UDP请求,udp的端口是在客户端发送获取实例请求时传给后端的,也就是说没有发送给服务发现请求的客户端不可能收到这个udp请求。

四、客户端服务发现源码

   1. 客户端会将从服务端拉取的服务信息缓存在本地的map中。服务发现先从本地服务取,没有再从服务端取,取到后放入本地map中。

    2.. 除此之外,在请求末尾还会发起一个定时任务,每过5秒从服务端拉取最新的服务信息。

 

相关文章
|
存储 关系型数据库 MySQL
Nacos 2.0.3和Nacos 2.2.3版本
Nacos 2.0.3和Nacos 2.2.3版本
822 1
|
27天前
|
网络协议 Java Nacos
Nacos的应用
Nacos的应用
43 0
|
5月前
|
SQL 关系型数据库 MySQL
详解nacos使用
详解nacos使用
103 0
|
负载均衡 前端开发 网络协议
是时候了解下 nacos 了!(一)
是时候了解下 nacos 了!(一)
|
Nacos
Nacos 配置文件属性说明
Nacos 配置文件属性说明
205 0
|
6月前
|
Nacos
Nacos的某些配置
Nacos的某些配置
64 2
|
12月前
|
存储 运维 网络安全
Nacos使用总结
Nacos使用总结
194 0
|
存储 负载均衡 Java
Nacos
Nacos
624 0
|
负载均衡 网络协议 前端开发
是时候了解下 nacos 了!(二)
是时候了解下 nacos 了!(二)
|
网络协议 Java 测试技术
详解Nacos
详解Nacos
361 0