nacos 中的服务和实例

service 对应的概念

用 namespace, group, serviceName 标识一个服务

从该属性可以看出服务的层级

// Map<namespace, Map<group::serviceName, Service>>
com.alibaba.nacos.naming.core.ServiceManager#serviceMap

服务和实例的对应关系

service, cluster, instance

从 2 个方法可以看出实例的层级

// com.alibaba.nacos.naming.core.Service#allIPs()
public List<Instance> allIPs() {
    List<Instance> allIPs = new ArrayList<>();
    for (Map.Entry<String, Cluster> entry : clusterMap.entrySet()) {
        allIPs.addAll(entry.getValue().allIPs());
    }

    return allIPs;
}

// com.alibaba.nacos.naming.core.Cluster#allIPs()
public List<Instance> allIPs() {
    List<Instance> allInstances = new ArrayList<>();
    // private Set<Instance> persistentInstances = new HashSet<>();
    allInstances.addAll(persistentInstances);
    // private Set<Instance> ephemeralInstances = new HashSet<>();
    allInstances.addAll(ephemeralInstances);
    return allInstances;
}

但是服务还有另外一种扁平的数据结构

以临时服务为例
DistroConsistencyServiceImpl
DataStore 使用 Map<String, Datum> 存储 Datum。
Datum 封装了 key 和 value,实际使用时 value 是 Instances

服务对应一个 key,如下是一个临时实例的 key:

com.alibaba.nacos.naming.iplist.ephemeral.public##DEFAULT_GROUP@@service-consumer

层级的数据结构响应客户端请求,扁平的数据结构在 nacos 节点之间用作数据传输。

一个 naming 客户端绑定一个 namespace

@CanDistro 注解

修改服务实例的 Controller method,会打上 CanDistro 注解,表明这个请求由固定节点处理

FilterBase 类,利用发射生成请求 URL 到 Controller Method 的映射:

private ConcurrentMap<String, Method> methodCache = new ConcurrentHashMap<>();

在 DistroFilter.doFilter 中,
1. 根据请求 URL 获取 Controller Method
2. 如果该 Method 对象有 CanDistro 注解,同时对 group + serviceName 哈希取模,决定处理请求的 nacos 节点
3. 如果当前 service 由其他节点负责,则把请求转发给其他节点

实例数据保存在本地内存后,产生 2 个异步动作:
1. 推送服务信息给 naming 客户端,由 Notifier 执行
2. 广播给集群中的其他节点,由 TaskDispatcher 执行

总结:某个 service 的修改请求由指定的 nacos 节点处理,修改之后数据会同步给其他 nacos 节点。所有的 nacos 节点保存全量的服务元数据。

猜你喜欢

转载自www.cnblogs.com/allenwas3/p/12115582.html