【Nacos架构 & 原理】内核设计之Nacos寻址机制

文章目录

前提

对于集群模式,集群内的每个Nacos成员都需要相互通信。因此这就带来一个问题,该以何种方式去管理集群内部的Nacos成员节点信息,即Nacos内部的寻址机制。

设计

要能够感知到节点的变更情况 :节点是增加了还是减少了;当前最新的成员列表信息是什么;以何种方式去管理成员列表信息;如何快速的支持新的、更优秀的成员列表管理模式等等。

针对上述需求点,我们抽象出了一个 MemberLookup 接口,具体设计如下:

java 复制代码
public interface MemberLookup {
    
    /**
     * start.
     *
     * @throws NacosException NacosException
     */
    void start() throws NacosException;
    
    /**
     * Inject the ServerMemberManager property.
     *
     * @param memberManager {@link ServerMemberManager}
     */
    void injectMemberManager(ServerMemberManager memberManager);
    
    /**
     * The addressing pattern finds cluster nodes.
     *
     * @param members {@link Collection}
     */
    void afterLookup(Collection<Member> members);
    
    /**
     * Addressing mode closed.
     *
     * @throws NacosException NacosException
     */
    void destroy() throws NacosException;
}

ServerMemberManager 存储着本节点所知道的所有成员节点列表信息 ,提供了针对成员节点的增删改查操作,同时维护了一个 MemberLookup 列表,方便进行动态切换成员节点寻址方式。)

可以看到,MemberLookup 接口非常简单,核心接口就两个------ injectMemberManager 以及 afterLookup前者 用于将 ServerMemberManager 注入MemberLookup 中,方便利用 ServerMemberManager 的存储、查询能力,后者 afterLookup 则是一个事件接口 ,当 MemberLookup 需要进行成员节点信息更新时,会将当前最新的成员节点列表信息通过该函数进行通知ServerMemberManager,具体的节点管理方式,则是隐藏到具体的 MemberLookup 实现中。

内部实现
单机寻址

com.alibaba.nacos.core.cluster.lookup.StandaloneMemberLookup

单机模式的寻址模式很简单,其实就是找到自己的IP:PORT组合信息 ,然后格式化为一个节点信息,调用afterLookup 然后将信息存储到 ServerMemberManager 中。

java 复制代码
public class StandaloneMemberLookup extends AbstractMemberLookup {
    
    @Override
    public void start() {
        if (start.compareAndSet(false, true)) {
            String url = InetUtils.getSelfIp() + ":" + ApplicationUtils.getPort();
            afterLookup(MemberUtils.readServerConf(Collections.singletonList(url)));
        }
    }
}
文件寻址

com.alibaba.nacos.core.cluster.lookup.FileConfigMemberLookup

文件寻址模式是 Nacos 集群 模式下的默认 寻址实现。文件寻址模式很简单,其实就是每个 Nacos 节点需要维护一个叫做 cluster.conf 的文件,如下;

plain 复制代码
192.168.16.101:8847
192.168.16.102
192.168.16.103

该文件默认只需要 填写每个成员节点的 IP 信息即可 ,端口会自动选择 Nacos 的默认端口 8848 ,如果说有特殊需求更改了 Nacos 的端口 信息,则需要在该文件将该节点的完整网路地址信息补充完整 (IP:PORT)

当 Nacos节点启动时,会读取该文件的内容,然后将文件内的 IP 解析为节点列表,调用 afterLookup 存入ServerMemberManager

java 复制代码
private void readClusterConfFromDisk() {
    Collection<Member> tmpMembers = new ArrayList<>();
    try {
        List<String> tmp = ApplicationUtils.readClusterConf();
        tmpMembers = MemberUtils.readServerConf(tmp);
    } catch (Throwable e) {
        Loggers.CLUSTER
                    .error("nacos-XXXX [serverlist] failed to get serverlist from disk!, error : {}", e.getMessage());
    }
     afterLookup(tmpMembers);
}

如果发现集群扩缩容 ,那么就需要修改每个 Nacos 节点下的 cluster.conf 文件 ,然后 Nacos 内部的文件变动监听中心会自动发现文件修改,重新读取文件内容、加载 IP 列表信息、更新新增的节点。

java 复制代码
private FileWatcher watcher = new FileWatcher() {
    @Override
    public void onChange(FileChangeEvent event) {
        readClusterConfFromDisk();
    }
        
    @Override
    public boolean interest(String context) {
        return StringUtils.contains(context, "cluster.conf");
    }
};

public void start() throws NacosException {
    if (start.compareAndSet(false, true)) {
        readClusterConfFromDisk();
            
        // Use the inotify mechanism to monitor file changes and automatically
        // trigger the reading of cluster.conf
        try {
            WatchFileCenter.registerWatcher(ApplicationUtils.getConfFilePath(), watcher);
        } catch (Throwable e) {
            Loggers.CLUSTER.error("An exception occurred in the launch file monitor : {}", e.getMessage());
        }
    }
}

默认寻址模式 有一个缺点 ------运维成本较大 ,可以想象下,当你新增一个 Nacos 节点时,需要去手动修改每个 Nacos 节点下的 cluster.conf 文件,这是多么辛苦的一件工作,或者稍微高端一点,利用 ansible 等自动化部署的工具去推送 cluster.conf 文件去代替自己的手动操作,虽然说省去了较为繁琐的人工操作步骤,但是仍旧存在一个问题------每一个 Nacos 节点都存在一份 cluster.conf 文件,如果其中一个节点的 cluster.conf 文件修改失败,就造成了集群间成员节点列表数据的不一致性 ,因此,又引申出了新的寻址模式------地址服务器寻址模式

地址服务器寻址

com.alibaba.nacos.core.cluster.lookup.AddressServerMemberLookup

地址服务器寻址模式是 Nacos 官方推荐的一种集群成员节点信息管理,该模式利用了一个简易的 web 服务器用于管理 cluster.conf 文件 的内容信息,这样,运维人员只需要管理这一份集群成员节点内容即可 ,而每个Nacos 成员节点,只需要向这个 web 节点定时请求当前最新的集群成员节点列表信息即可

因此,通过地址服务器这种模式,大大简化了 Nacos 集群节点管理的成本,同时,地址服务器是一个非常简单的 web 程序,其程序的稳定性能够得到很好的保障。

相关推荐
qq_3273427315 分钟前
Java实现离线身份证号码OCR识别
java·开发语言
Kkooe1 小时前
GitLab|数据迁移
运维·服务器·git
阿龟在奔跑1 小时前
引用类型的局部变量线程安全问题分析——以多线程对方法局部变量List类型对象实例的add、remove操作为例
java·jvm·安全·list
飞滕人生TYF2 小时前
m个数 生成n个数的所有组合 详解
java·递归
代码小鑫2 小时前
A043-基于Spring Boot的秒杀系统设计与实现
java·开发语言·数据库·spring boot·后端·spring·毕业设计
真心喜欢你吖2 小时前
SpringBoot与MongoDB深度整合及应用案例
java·spring boot·后端·mongodb·spring
激流丶2 小时前
【Kafka 实战】Kafka 如何保证消息的顺序性?
java·后端·kafka
周全全2 小时前
Spring Boot + Vue 基于 RSA 的用户身份认证加密机制实现
java·vue.js·spring boot·安全·php
uzong3 小时前
一个 IDEA 老鸟的 DEBUG 私货之多线程调试
java·后端
AiFlutter3 小时前
Java实现简单的搜索引擎
java·搜索引擎·mybatis