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 provider | db type | 连接字符串 |
---|---|---|
sqlserver | SQL Server | Data Source=127.0.0.1,1433;Initial Catalog=agile_config;User Id=chait;Password=123456;TrustServerCertificate=true;Pooling=true;Max Pool Size=50 |
mysql | MySQL | Data Source=127.0.0.1;Port=3306;Initial Catalog=agile_config;User ID=chait;Password=123456;Charset=utf8mb4;SslMode=none;Max pool size=50 |
sqlite | Sqlite | Data Source=agile_config.db;Version=3;UseUTF16Encoding=True;Password=123456;Pooling=true;FailIfMissing=false;Max Pool Size=50 |
npgsql | PostgreSQL | Server=127.0.0.1;Port=5432;Database=agile_config;Username=chait;Password=123456;Pooling=true;Maximum Pool Size=50 |
oracle | Oracle | Data 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
中读取上述配置。
- 在
appsettings.json
文件(默认根文件)配置agileconfig
的配置信息。
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseAgileConfig(e => Console.WriteLine($"configs {e.Action}"))
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
- 使用
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>();
});
- 使用
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;
}
/// <summary>
/// 使用 IConfiguration 读取配置
/// </summary>
/// <returns></returns>
[HttpGet(ByIConfiguration)]
public IActionResult ByIConfiguration()
{
string aaa = _configuration["Abc:aaa"];
string info = $"Abc.aaa={aaa}";
_logger.LogInformation(info);
return Ok(info);
}
/// <summary>
/// 使用 IConfigClient 读取配置
/// </summary>
/// <returns></returns>
[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
开发的轻量级配置中心,方便好用!