1Nacos 配置中心源码解析之 Hello World

Posted carl-zhao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1Nacos 配置中心源码解析之 Hello World相关的知识,希望对你有一定的参考价值。

在单体架构的时候我们可以将配置写在配置文件中,但有⼀个缺点就是每次修改配置都需要重启服务才能生效。当应用程序实例比较少的时候还可以维护。如果转向微服务架构有成百上千个实例,每修改⼀次配置要将全部实例重启,不仅增加了系统的不稳定性,也提高了维护的成本。


那么如何能够做到服务不重启就可以修改配置?所有就产生了四个基础诉求:

  • 需要支持动态修改配置
  • 需要动态变更有多实时
  • 变更快了之后如何管控控制变更风险,如灰度、回滚等
  • 敏感配置如何做安全配置

1、概念介绍

1.1 配置(Configuration)

在系统开发过程中通常会将⼀些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配
置文件的形式存在。目的是让静态的系统工件或者交付物(如WAR,JAR 包等)更好地和实际的物
理运行环境进行适配。配置管理⼀般包含在系统部署的过程中,由系统管理员或者运维人员完成这
个步骤。配置变更是调整系统运行时的行为的有效手段之⼀。

1.2 配置管理(Configuration Management)

在Nacos 中,系统中所有配置的存储、编辑、删除、灰度管理、历史版本管理、变更审计等所有
与配置相关的活动统称为配置管理。

1.3 配置服务(Configuration Service)

在服务或者应用运行过程中,提供动态配置或者元数据以及配置管理的服务提供者。

1.4 配置项(Configuration Item)

⼀个具体的可配置的参数与其值域,通常以param-key = param-value 的形式存在。例如我们常
配置系统的日志输出级别(logLevel = INFO | WARN | ERROR) 就是⼀个配置项。

1.5 配置集(Configuration Set)

⼀组相关或者不相关的配置项的集合称为配置集。在系统中,⼀个配置文件通常就是⼀个配置集,
包含了系统各个方面的配置。例如,⼀个配置集可能包含了数据源、线程池、日志级别等配置项。

1.6 命名空间(Namespace)

用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的Group 或Data ID 的配置。
Namespace 的常用场景之⼀是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源
(如数据库配置、限流阈值、降级开关)隔离等。如果在没有指定Namespace 的情况下,默认使
用public 命名空间。

1.7 配置组(Group)

Nacos 中的⼀组配置集,是配置的维度之⼀。通过⼀个有意义的字符串(如ABTest 中的实验组、
对照组)对配置集进行分组,从而区分Data ID 相同的配置集。当您在Nacos 上创建⼀个配置时,
如果未填写配置分组的名称,则配置分组的名称默认采用DEFAULT_GROUP 。配置分组的常见场
景:不同的应用或组件使用了相同的配置项,如database_url 配置和MQ_Topic 配置。

1.8 配置ID(Data ID)

Nacos 中的某个配置集的ID。配置集ID 是划分配置的维度之⼀。Data ID 通常用于划分系统的配
置集。⼀个系统或者应用可以包含多个配置集,每个配置集都可以被⼀个有意义的名称标识。Data
ID 尽量保障全局唯⼀,可以参考Nacos Spring Cloud 中的命名规则:

$prefix-$spring.profiles.active-$file-extension

1.9 配置快照(Configuration Snapshot)

Nacos 的客户端SDK 会在本地生成配置的快照。当客户端无法连接到Nacos Server 时,可以使
用配置快照显示系统的整体容灾能力。配置快照类似于Git 中的本地commit,也类似于缓存,会
在适当的时机更新,但是并没有缓存过期(expiration)的概念。

2、Nacos 配置模型

2.1 基础模型


上图是Nacos 配置管理的基础模型:

  1. Nacos 提供可视化的控制台,可以对配置进行发布、更新、删除、灰度、版本管理等功能。
  2. SDK 可以提供发布配置、更新配置、监听配置等功能。
  3. SDK 通过GRPC 长连接监听配置变更,Server 端对比Client 端配置的MD5 和本地MD5
    是否相等,不相等推送配置变更。
  4. SDK 会保存配置的快照,当服务端出现问题的时候从本地获取。

2.2 配置资源模型

Namespace 的设计就是用来进行资源隔离的,我们在进行配置资源的时候可以从以下两个角度来
看:

从单个租户的角度来看,我们要配置多套环境的配置,可以根据不同的环境来创建Namespace 。
比如开发环境、测试环境、线上环境,我们就创建对应的Namespace(dev、test、prod),
Nacos 会自动生成对应的Namespace Id 。如果同⼀个环境内想配置相同的配置,可以通过
Group 来区分。如下图所示:


从多个租户的角度来看,每个租户都可以有自己的命名空间。我们可以为每个用户创建⼀个命名空
间,并给用户分配对应的权限,比如多个租户(zhangsan、lisi、wangwu),每个租户都想有⼀套
自己的多环境配置,也就是每个租户都想配置多套环境。那么可以给每个租户创建⼀个Namespac
e (zhangsan、lisi、wangwu)。同样会生成对应的Namespace Id。然后使用Group 来区分不
同环境的配置。如下图所示:

2.3 配置存储模型(ER 图)


Nacos 存储配置有几个比较重要的表分别是:

  • config_info 存储配置信息的主表,里面包含dataId、groupId、content、tenantId、encrypt
    edDataKey 等数据。
  • config_info_beta 灰度测试的配置信息表,存储的内容和config_info 基本相似。有⼀个beta
    _ips 字段用于客户端请求配置时判断是否是灰度的ip。
  • config_tags_relation 配置的标签表,在发布配置的时候如果指定了标签,那么会把标签和配置
    的关联信息存储在该表中。
  • his_config_info 配置的历史信息表,在配置的发布、更新、删除等操作都会记录⼀条数据,可
    以做多版本管理和快速回滚。

3、启动 Nacos

您可以在 Nacos 的 release notes博客 中找到每个版本支持的功能的介绍,当前推荐的稳定版本为2.0.3。

3.1 预备环境准备

Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行Nacos,还需要为此配置 Maven环境,请确保是在以下版本环境中安装使用:

  • 64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用 Linux/Unix/Mac。
  • 64 bit JDK 1.8+;
  • Maven 3.2.x+;

3.2 下载源码或者安装包

你可以通过源码和发行包两种方式来获取 Nacos。

从 Github 上下载源码方式

git clone https://github.com/alibaba/nacos.git
cd nacos/
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U  
ls -al distribution/target/

// change the $version to your actual path
cd distribution/target/nacos-server-$version/nacos/bin

下载编译后压缩包方式
您可以从 最新稳定版本 下载 nacos-server-$version.zip 包。

  unzip nacos-server-$version.zip 或者 tar -xvf nacos-server-$version.tar.gz
  cd nacos/bin

3.3 启动服务器

注:Nacos的运行需要以至少2C4g60g*3的机器配置下运行。

Linux/Unix/Mac

启动命令(standalone代表着单机模式运行,非集群模式):

sh startup.sh -m standalone

如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行:

bash startup.sh -m standalone

Windows

启动命令(standalone代表着单机模式运行,非集群模式):

startup.cmd -m standalone

启动成功,可以在浏览器输入 http://localhost:8848/nacos 进行访问:

然后使用默认的用户名密码:nacos/nacos 进行登录:

4、配置管理

4.1 Rest API 方式

发布配置

curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld"

发布配置成功后:

并且点击详情可以看到配置的值:

获取配置

curl -X GET "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test"

4.2 SDK 方式

package com.alibaba.nacos.example;

import java.util.Properties;
import java.util.concurrent.Executor;

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;

/**
 * Config service example.
 *
 * @author Nacos
 */
public class ConfigExample 

    public static void main(String[] args) throws NacosException, InterruptedException 
        String serverAddr = "localhost";
        String dataId = "test";
        String group = "DEFAULT_GROUP";
        Properties properties = new Properties();
        properties.put("serverAddr", serverAddr);
        ConfigService configService = NacosFactory.createConfigService(properties);
        // #1 获取获取配置
        String content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);
        // #2 添加监听器
        configService.addListener(dataId, group, new Listener() 
            @Override
            public void receiveConfigInfo(String configInfo) 
                System.out.println("receive:" + configInfo);
            

            @Override
            public Executor getExecutor() 
                return null;
            
        );

		// #3 发布配置
        boolean isPublishOk = configService.publishConfig(dataId, group, "content");
        System.out.println(isPublishOk);

		// #4 获取配置
        Thread.sleep(3000);
        content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);

		// #5 删除配置
        boolean isRemoveOk = configService.removeConfig(dataId, group);
        System.out.println(isRemoveOk);
        Thread.sleep(3000);

		// #6 再次获取配置
        content = configService.getConfig(dataId, group, 5000);
        System.out.println(content);
        Thread.sleep(300000);
    

运行结果如下:

  • #1 首次获取配置,如果之前没有配置返回值为空
  • #2 添加配置添加器,当配置发生变更时会回调这个监听器
  • #3 发布配置到 Nacos,发布成功之后,在下面打断点会出现下面的配置。并且会回调步骤2添加的监听器。
  • #4 获取刚刚发布的配置会得到 content 这个字段串
  • #5 删除第 3 步发布在 Nacos 上面的配置
  • #6 由于第 5 步删除了配置,所以从 Nacos 中获取到的配置为 null。

参考文章:

  • https://developer.aliyun.com/ebook/36
  • https://nacos.io/zh-cn/docs/quick-start.html

以上是关于1Nacos 配置中心源码解析之 Hello World的主要内容,如果未能解决你的问题,请参考以下文章

1Nacos 配置中心源码解析之 Hello World

1Nacos 配置中心源码解析之 集成 Spring Cloud

1Nacos 配置中心源码解析之 集成 Spring Cloud

3Nacos 配置中心源码解析之 项目结构

3Nacos 配置中心源码解析之 项目结构

4Nacos 配置中心源码解析之 服务端启动