【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 程序,其程序的稳定性能够得到很好的保障。

相关推荐
l1t2 小时前
DeepSeek 4.1总结的Tom Lane 谈塑造 Postgres 三十年历程的架构决策
开发语言·数据库·postgresql·架构
欢迎来到祖安!2 小时前
企业微信 API 接口能力介绍:支持消息收发、图片发送、表情互动、联系人管理等多场景应用
java·前端·数据仓库·spring cloud·企业微信
dadaobusi6 小时前
学习:RV lkvm SBI
java·学习·spring
Dawson Zhu8 小时前
工作流与 Agent 的工程选型:从“控制权归属“看 LLM 应用架构
人工智能·语言模型·架构·aigc·agi
HEJOO98 小时前
深入理解 Java volatile 关键字:原理、用法与常见误区
java·开发语言·spring
曹牧8 小时前
Java:no content to map due to end of input
java·开发语言
阿维的博客日记8 小时前
Example 类全场景实战指南
java·mybatis
两点王爷8 小时前
SpringBoot 项目集成 GeoServer 源码,实现地图服务发布
java·spring boot·后端
Javatutouhouduan9 小时前
Java如何速通性能优化难题?
java·java面试·jvm调优·后端开发·java程序员·java八股文·java性能优化
lemon_sjdk9 小时前
DOM 节点
java·前端·javascript