基于.net core 开发的轻量级配置中心 - AgileConfig

基于.net core 开发的轻量级配置中心 - AgileConfig,第1张

AgileConfig 简介

是一个基于 .net core 开发的轻量级配置中心。

目标或解决的问题

AgileConfig 并不是为了什么微服务,更多的是为了那些分布式、容器化部署的应用能够更加简单的读取、修改配置。

AgileConfig 特点

秉承轻量化的,部署简单、配置简单、使用简单、学习简单,它只提取了必要的一些功能,并没有像 Apollo 那样复杂且庞大。但是它的功能也已经足够你替换 web.config,appsettings.json 这些文件了。

如果你不想用微服务全家桶,不想为了部署一个配置中心而需要看 N 篇教程跟几台服务器那么你可以试试 AgileConfig。

  • 部署简单,最少只需要一个数据节点,支持docker部署
  • 支持多节点分布式部署来保证高可用
  • 配置支持按应用隔离,应用内配置支持分组隔离
  • 支持多环境
  • 应用支持继承,可以把公共配置提取到一个应用然后其它应用继承它
  • 使用长连接技术,配置信息实时推送至客户端
  • 支持 IConfiguration,IConfigClient,IOptions 模式读取配置,原程序几乎可以不用改造
  • 配置修改支持版本记录,随时回滚配置
  • 如果所有节点都故障,客户端支持从本地缓存读取配置
  • 支持Restful API维护配置
  • v-1.6.0 以上已支持服务注册与发现
参考地址
  • Github:https://github.com/dotnetcore/AgileConfig
  • Gitee:https://gitee.com/kklldog/AgileConfig
  • AgileConfig releases:https://github.com/dotnetcore/AgileConfig/releases
  • AgileConfig Change log:https://github.com/dotnetcore/AgileConfig/blob/master/CHANGELOG.md
  • Docker 镜像:https://hub.docker.com/r/kklldog/agile_config
  • 作者博客:https://www.cnblogs.com/kklldog/p/agile-config.html
AgileConfig 架构介绍

AgileConfig的架构比较简单,主要是分3块:

客户端(Client)

客户端程序是使用 netstandard2.0 开发的一个类库,方便 .net core 程序接入,nuget 搜AgileConfig.Client 就可以安装。可以在启动客户端的时候配置多个节点的地址,客户端会随机挑选一个进行连接,连接成功后会维持一个websocket长连接。如果连接的节点发生故障导致连接中断,客户端会继续随机一个节点进行连接,直到连接成功。

节点、管理程序(Node Server、Console)

节点是使用 asp.net core 开发的一个服务。为了部署简单,直接把管理程序跟节点服务合二为一了。任何一个节点都可以在启动的时候配置环境变量开启管理程序功能。

数据库(Database)

使用数据库来存储数据,目前支持Sqlserver, Mysql, Sqlite, PostgreSql, Oracle 五种数据库。最新版本已经切换为Freesql为数据访问组件。Freesql对多数据库的支持更加强劲,特别是对国产数据库的支持。但是因为没有国产数据库的测试环境,本项目并未支持,如果有需要我可是开分支尝试支持,但是测试工作就要靠用户啦。

注意:如果使用 <=1.0.4 之前版本的用户请不要更新,因为 EFCore 跟 FreeSql 自动建的库可能存在稍许差异,保险起见不要更新吧。

关于高可用

AgileConfig 的节点都是无状态的,所以可以横向部署多个节点来防止单点故障。在客户端配置多个节点地址后,客户端会随机连接至某个节点。

问题影响说明
控制台下线无法维护配置,客户端无影响因为控制台跟节点是共存的,所以某个控制台下线一般来说同样意味着一个节点的下线
某个节点下线客户端重连至其他节点无任何影响
所有节点下线客户端从内存读取配置启动的客户端会从内存读取配置,未启动的客户端会再尝试连接到节点多次失败后,尝试从本地文件缓存读取配置,保证应用可以启动

注意:结合 DB 数据库的高可用技术搭配使用。

AgileConfig 服务端搭建 初始化 DB 数据库

用户只需要手工建一个空库,所有的表在第一次启动的时候都会自动生成。目前支持 SqlServer,MySQL,Sqlite, PostgreSQL,Oracle 五种数据库。


docker 运行服务端项目即可初始化对应的数据库,此处以 PostgreSQL 数据库为例。

DB Provider 对照表

数据名称:agile_config,用户:chait,密码:123456

db providerdb type连接字符串
sqlserverSQL ServerData Source=127.0.0.1,1433;Initial Catalog=agile_config;User Id=chait;Password=123456;TrustServerCertificate=true;Pooling=true;Max Pool Size=50
mysqlMySQLData Source=127.0.0.1;Port=3306;Initial Catalog=agile_config;User ID=chait;Password=123456;Charset=utf8mb4;SslMode=none;Max pool size=50
sqliteSqliteData Source=agile_config.db;Version=3;UseUTF16Encoding=True;Password=123456;Pooling=true;FailIfMissing=false;Max Pool Size=50
npgsqlPostgreSQLServer=127.0.0.1;Port=5432;Database=agile_config;Username=chait;Password=123456;Pooling=true;Maximum Pool Size=50
oracleOracleData Source=//127.0.0.1:1521/XE;User Id=chait;Password=123456;Pooling=true;Max Pool Size=50
Docker 部署服务端 docker run 命令运行服务端
  • 拉取 agile_config 镜像
docker pull kklldog/agile_config:latest
  • 运行 agile_config 容器
sudo docker run \
 --name agile_config \
 -e TZ=Asia/Shanghai \
 -e adminConsole=true \
 -e db:provider=sqlite \
 -e db:conn="Data Source=agile_config.db;Version=3;UseUTF16Encoding=True;Password=123456;Pooling=true;FailIfMissing=false;Max Pool Size=50" \
 -p 15000:5000 \
 -v /agileconfig:/app/db \
 -d \
 kklldog/agile_config:latest

参数说明:

  • name:容器名,指定个容器名。
  • TZ:指定时区。
  • adminConsole:配置程序是否使用管理控制台。如果为true则启用控制台功能,访问该实例会出现管理界面。
  • 每个实例都可以选择使用管理界面,共用一套数据源只是呈现端口不同。默认账号为 admin,首次登录需要设置密码,设置后多个管理界面都可以通用。
  • db:provider:配置程序的数据库类型。目前程序支持:sqlite,mysql,sqlserver,npgsql, oracle 五种数据库。按照项目中允许的数据库使用即可。首个节点启动后会创建数据表(相当好~)。
  • db:env:{env}:provider,可以指定特定环境下使用某个数据库,如【db:env:PROD.provider=sqlserver, db:env:DEVELOPMENT.provider=mysql】。
  • db:conn:配置数据库连接串。按照不同的数据库类型设置不同的数据库连接字符串。
    数据库使用第二步创建的库。 默认内置了 DEV, TEST, STAGING, PROD 四个常用的环境,如不够,可直接 *** 作 agc_setting 表,增加自定义环境。
  • db:env:{env}:conn,可以指定特定环境下使用某个数据库,如 【db:env:PROD.conn=xxx, db:env:DEVELOPMENT.conn=xxx】。
  • p:指定对外端口,用户客户端去连接。设置允许使用的对外端口即可。
  • v:节点的数据卷挂载。此处挂载到第一步设置的文件夹路径下,可按实际需要设置挂载路径或是不设置 -v 参数也行。
  • -d:设置容器后台运行。

通过 docker 建立一个 agile_config 容器实例,其中有 3 个环境变量需要配置:

  • adminConsole 配置程序是否为管理控制台。如果为 true 则启用控制台功能,访问该实例会出现管理界面。
  • db:provider 配置程序的数据库类型。目前程序支持:sqlite,mysql,sqlserver,npgsql,oracle 五种数据库。
  • db:conn 配置数据库连接串。
docker compose 运行服务端

除了上面的 docker run 的方式运行 agile_config 容器实例,还可以使用 docker compose 来快速创建,此处以 postgresql 数据库为例,编写 yaml 文件如下:

version: '3'
services:
  agile_config_admin:
    image: "kklldog/agile_config:latest"
    ports:
      - "15000:5000"
    networks:
      - net0
    volumes:
      - /etc/localtime:/etc/localtime
    environment:
      - TZ=Asia/Shanghai
      - adminConsole=true
      - nodes=agile_config_admin:5000,agile_config_node1:5000,agile_config_node2:5000
      - db:provider=npgsql
      - db:conn= Server=Server=127.0.0.1;Port=5432;Database=agile_config;Username=chait;Password=123456;Pooling=true;Maximum Pool Size=50
  agile_config_node1:
    image: "kklldog/agile_config:latest"
    ports:
      - "15001:5000"
    networks:
      - net0
    volumes:
      - /etc/localtime:/etc/localtime
    environment:
      - TZ=Asia/Shanghai
      - db:provider=npgsql
      - db:conn= Server=127.0.0.1;Port=5432;Database=agile_config;Username=chait;Password=123456;Pooling=true;Maximum Pool Size=50
    depends_on:
      - agile_config_admin
  agile_config_node2:
    image: "kklldog/agile_config:latest"
    ports:
      - "15002:5000"
    networks:
      - net0
    volumes:
      - /etc/localtime:/etc/localtime
    environment:
      - TZ=Asia/Shanghai
      - db:provider=npgsql
      - db:conn= Server=127.0.0.1;Port=5432;Database=agile_config;Username=chait;Password=123456;Pooling=true;Maximum Pool Size=50
    depends_on:
      - agile_config_admin
networks:
  net0:

注意:如果通过 IIS 或者别的方式部署,请自行从主页上的 releases 页面下载最新的部署包。如果自己使用源码编译,请先编译 react-ui-antd 项目把 dist 内的产物复制到 apisite 项目的 wwwroot/ui 目录下。

浏览器查看 AgileConfig 管理界面

浏览器输入如下地址:

http://localhost:15000/ui#/user/login
http://localhost:15000/ui#/home

看到如下界面,说明 AgileConfig 服务端已经部署成功。

注意:第一次运行程序需要初始化管理员密码。

AgileConfig 管理界面介绍

菜单说明
菜单说明
首页显示一些相关指标的统计数据。
节点AgileConfig 支持多节点部署,所有的节点都是平行的。为了简化部署,AgileConfig 并没有单独的控制台程序,请直接使用任意一个节点作为控制台。当环境变量 adminConsole=true 时,该节点同时兼备数据节点跟控制台功能。为了控制台能够管理节点,所以需要在控制台配置节点的信息。
注意:即使是作为控制台的数据节点同样需要添加到管理程序,以便管理它。
应用AgileConfig 支持多应用程序接入。需要为每个应用程序配置名称、ID、秘钥等信息。每个应用可以设置是否可以被继承,可以被继承的应用类似 apollo 的公共 namespace 的概念。
公共的配置可以提取到可继承应用中,其它应用只要继承它就可以获得所有配置。
如果子应用跟被继承应用之间的配置键发生重复,子应用的配置会覆盖被继承的应用的配置。子应用可以继承多个应用,如果多个应用之间发生重复键,按照继承的顺序,后继承的应用的配置覆盖前面的应用。
配置项配置完应用信息后可以为每个应用配置配置项。配置项支持分组。新添加的配置并不会被客户端感知到,需要手工点击“上线”才会推送给客户端。已上线的配置如果发生修改、删除、回滚 *** 作,会实时推送给客户端。版本历史记录了配置的历史信息,可以回滚至任意版本。
客户端控制台可以查看已连接的客户端。
日志系统日志记录了 AgileConfig 生产中的一些关键信息。
用户可以添加管理配置中心的用户人员信息,用户组,角色。
AgileConfig 客户端使用

查看 nuget 包 =》https://www.nuget.org/packages/AgileConfig.Client/

新建 asp.net core webapi 项目,并添加 nuget 包【AgileConfig.Client】
  • 新建项目 WebApplication.AgileConfig ,项目结构如下:

注意:chait.agileconfig.client.configs.cache 该文件是本地缓存文件,运行项目后生成。

  • 在新建项目添加 nuget 包 AgileConfig.Client
Install-Package AgileConfig.Client -Version 1.6.1
  • 修改 appsettings.json/appsettings.Development.json 配置文件,添加 AgileConfig 配置
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  //agile_config
  "AgileConfig": {
    "appId": "chait",
    "secret": "xxx",
    "nodes": "http://192.168.10.251:15000,http://192.168.10.251:15001,http://192.168.10.251:15002", //多个节点使用逗号分隔,
    "name": "client_name",
    "tag": "tag1",
    "env": "DEV",
    "httpTimeout": "100",
    "cache": {
      "directory": "Config"
    }
  }
}

agile_config 配置项说明

  • 修改 Program.cs 文件,在 Program.cs 设置使用 AgileConfig,如此增加环境后,AgileConfigProvider便会从相应环境 appsettings.json 中读取上述配置
  1. 在 appsettings.json 文件(默认根文件)配置 agileconfig 的配置信息。
 public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
            .UseAgileConfig(e => Console.WriteLine($"configs {e.Action}"))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
  1. 使用 UseAgileConfig 扩展方法设置一个配置源。
public static IHostBuilder CreateHostBuilder(string[] args) =>
               Host.CreateDefaultBuilder(args)
               .UseAgileConfig(new ConfigClient($"Config\appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json"), e => Console.WriteLine($"Action={e.Action},Key={e.Key}"))
               .ConfigureWebHostDefaults(webBuilder =>
               {
                  webBuilder.UseStartup<Startup>();
               });
  1. 使用 ConfigureAppConfiguration 扩展方法设置一个配置源。
public static IHostBuilder CreateHostBuilder(string[] args) => 
            Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.Sources.Clear();

                // 获取宿主机环境变量
                var env = hostingContext.HostingEnvironment;
                //Console.WriteLine($"HostingEnvironment:ApplicationName={env.ApplicationName},EnvironmentName={env.EnvironmentName},ContentRootPath={env.ContentRootPath}");

                //string basePath = Path.Join(AppContext.BaseDirectory, "Config");
                //string basePath = Path.Join(Directory.GetCurrentDirectory(), "Config");
                string basePath = Path.Join(env.ContentRootPath, "Config");

                // 设置 json 配置文件路径
                config.SetBasePath(basePath: basePath)
                        .AddJsonFile(path: "appsettings.json", optional: false, reloadOnChange: true)
                        .AddJsonFile(path: $"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

                if (args != null)
                {
                    config.AddCommandLine(args);
                }

                string configClientPath = string.Empty;
                if (env.IsProduction())
                {
                    configClientPath = $"{basePath}\appsettings.json";
                }
                else
                {
                    // 指定参数获取环境变量名称,等效于 env.EnvironmentName
                    var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
                    configClientPath = $"{basePath}\appsettings.{environmentName}.json";
                }

                // new一个client实例,传参指定本地 appsettings.json 文件路径读取配置
                var configClient = new ConfigClient(configClientPath);
                // 使用 AddAgileConfig 配置一个新的 IConfigurationSource 注册项,并输出修改事件信息
                config.AddAgileConfig(configClient, e => Console.WriteLine($"Action={e.Action},Key={e.Key}"));
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });

注意上面的2、3两种扩展方法是等效的,UseAgileConfig 扩展方法内部会设置 basePath 。

  • 在 Startup.cs 中添加服务
services.AddAgileConfig();
从 AgileConfig 配置中心读取客户端项目配置信息

AgileConfig 支持以下方式读取配置信息:

  • 支持 asp.net core 标准的 IConfiguration
  • IOptions 模式读取配置
  • AgileConfigClient 实例直接读取
  • IConfigClient 模式读取配置

新建 HomeController 文件,此处以为 IConfiguration,IConfigClient 为例,编写如下代码:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;

namespace WebApplication.AgileConfig.Controllers;

[Route("api/[controller]")]
[ApiController]
public class HomeController : ControllerBase
{
    private readonly ILogger<HomeController> _logger;
    private readonly IConfiguration _configuration;
    private readonly IConfigClient _configClient;
    
    public HomeController(ILogger<HomeController> logger, IConfiguration configuration, IConfigClient _configClient)
    {
        _logger = logger;
        _configuration = configuration;
        _configClient = configClient;
    }

    /// 
    /// 使用 IConfiguration 读取配置
    /// 
    /// 
    [HttpGet(ByIConfiguration)]
    public IActionResult ByIConfiguration()
    {
        string aaa = _configuration["Abc:aaa"];
        string info = $"Abc.aaa={aaa}";
        _logger.LogInformation(info);
        return Ok(info);
    }

    /// 
    /// 使用 IConfigClient 读取配置
    /// 
    /// 
    [HttpGet("ByIConfigClient")]
    public IActionResult ByIConfigClient()
    {
        var aaa = _configClient["Abc:aaa"];
        string info = $"Abc.aaa={aaa}";
        _logger.LogInformation(info);
        foreach (var item in _configClient.Data)
        {
            Console.WriteLine($"{item.Key} = {item.Value}");
        }
        return Ok(info);
    }
}

到此处客户端测试程序已经准备就绪,接下来在 AgileConfig 管理页面【应用】添加相关配置信息。

AgileConfig 配置中心读取配置的优先级

如果在 AgileConfig 中有则默认从那取值,没有再去找机密文件,再去找 appsettings.{env}.json,最后 appsettings.json,注意优先级最高的还是环境变量和命令行的配置。

  • https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-6.0#default-configuration
  • https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/?view=aspnetcore-6.0#default-configuration
AgileConfig 配置中心添加客户端项目配置信息

选择 AgileConfig 管理页面 =》【应用】,新建客户端应用的配置信息,注意和上面的 appsettings.json 文件里面的配置保持一致。如下所示:

点击【配置项】=》【新建】按钮,即可添加配置信息。

从上图中可以看到, AgileConfig 配置中心默认提供4个环境变量:DEV、TEST、STAGING、PROD,可以新增 key-value 键值对、json 结构数据和 text 文本信息配置。

新建配置信息

新建配置信息后,页面显示如下:

点击【发布】即可让新增的配置信息生效。

项目测试 dotnet cli 启动项目

使用 dotnet cli 启动 WebApplication.AgileConfig 项目,输出如下信息:

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:\Users\sws-dev-server\Desktop\dapr-demo\dapr-demo\WebApplication.AgileConfig> dotnet run

欢迎使用 .NET 6.0!
---------------------
SDK 版本: 6.0.300

遥测
---------
.NET 工具会收集用法数据,帮助我们改善你的体验。它由 Microsoft 收集并与社区共享。你可通过使用喜欢的 shell 将 DOTNET_CLI_TELEMETRY_OPTOUT 环境变量设置为 "1""true" 来选择退出遥测。

阅读有关 .NET CLI 工具遥测的更多信息: https://aka.ms/dotnet-cli-telemetry

----------------
已安装 ASP.NET Core HTTPS 开发证书。
若要信任该证书,请运行 "dotnet dev-certs https --trust" (仅限 Windows 和 macOS)。
了解 HTTPS: https://aka.ms/dotnet-https
----------------
编写你的第一个应用: https://aka.ms/dotnet-hello-world
查找新增功能: https://aka.ms/dotnet-whats-new
浏览文档: https://aka.ms/dotnet-docs
在 GitHub 上报告问题和查找源: https://github.com/dotnet/core
使用 "dotnet --help" 查看可用命令或访问: https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
正在生成...
trce: AgileConfig.Client.ConfigClient[0]
      client try connect to server ws://192.168.10.251:15001/ws?client_name=client_name&client_tag=tag1
trce: AgileConfig.Client.ConfigClient[0]
      client connect server ws://192.168.10.251:15001/ws?client_name=client_name&client_tag=tag1 successful .
trce: AgileConfig.Client.ConfigClient[0]
      client load all the configs success by API: http://192.168.10.251:15002/api/config/app/chait?env=DEV , try count: 0.
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\Users\sws-dev-server\Desktop\dapr-demo\dapr-demo\WebApplication.AgileConfig
查看【节点】信息

浏览器查看【节点】信息,如下所示:

  • 输入 http://localhost:15000/ui#/node

API 接口获取配置信息
  • 访问 HomeController 获取配置信息


以上就是在 asp.net core webapi 项目中使用 AgileConfig 配置中心的全部过程,欢迎更多的小伙伴使用,基于 .net core 开发的轻量级配置中心,方便好用!

参考资料
  • https://github.com/dotnetcore/AgileConfig
  • https://hub.docker.com/r/kklldog/agile_config
  • https://www.cnblogs.com/kklldog/p/agile-config.html

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/917323.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存