Giter Club home page Giter Club logo

agileconfig's Introduction

AgileConfig

Member project of .NET Core Community package workflow GitHub stars Commit Date Nuget Nuget Docker image GitHub license build workflow

这是一个基于.net core开发的轻量级配置中心。说起配置中心很容易让人跟微服务联系起来,如果你选择微服务架构,那么几乎逃不了需要一个配置中心。事实上我这里并不是要蹭微服务的热度。这个世界上有很多分布式程序但它并不是微服务。比如有很多传统的SOA的应用他们分布式部署,但并不是完整的微服务架构。这些程序由于分散在多个服务器上所以更改配置很困难。又或者某些程序即使不是分布式部署的,但是他们采用了容器化部署,他们修改配置同样很费劲。所以我开发AgileConfig并不是为了什么微服务,我更多的是为了那些分布式、容器化部署的应用能够更加简单的读取、修改配置。
AgileConfig秉承轻量化的特点,部署简单、配置简单、使用简单、学习简单,它只提取了必要的一些功能,并没有像Apollo那样复杂且庞大。但是它的功能也已经足够你替换webconfig,appsettings.json这些文件了。如果你不想用微服务全家桶,不想为了部署一个配置中心而需要看N篇教程跟几台服务器那么你可以试试AgileConfig :)

Gitee 镜像:https://gitee.com/kklldog/AgileConfig

❤️❤️ 演示地址:AgileConfig Server Demo 用户名:admin 密码:123456
.NET 客户端项目:AgileConfig_Client
JAVA 客户端项目:AgileConfig_JClient

示例项目:
AgileConfig MVCSample
AgileConfig WPFSample
AgileConfig ConsoleSample
💥💥教程(提问之前请看完以下文章):
教程 - 如何使用AgileConfig.Client读取配置
教程- 如何使用服务注册与发现
教程 - 如何开启 SSO
💥常见问题,必看!!!
关于多环境的部署说明
如何对接 OpenTelemetry 查看 log,trace,metric

社区资源:
🌷 基于 Nodejs 实现的客户端: node-agile-client
🌷 基于 Blazor 实现的管理界面:AgileConfigBlazorUI

Restful API:
✈️ restful api

ChangeLog

📝 Changelog

联系作者

📧 联系

打赏

❤️❤️❤️ 打赏

特点

  1. 部署简单,最少只需要一个数据节点,支持docker部署
  2. 支持多节点分布式部署来保证高可用
  3. 配置支持按应用隔离,应用内配置支持分组隔离
  4. 支持多环境
  5. 应用支持继承,可以把公共配置提取到一个应用然后其它应用继承它
  6. 使用长连接技术,配置信息实时推送至客户端
  7. 支持IConfiguration,IOptions模式读取配置,原程序几乎可以不用改造
  8. 配置修改支持版本记录,随时回滚配置
  9. 如果所有节点都故障,客户端支持从本地缓存读取配置
  10. 支持Restful API维护配置
  11. v-1.6.0 以上已支持服务注册与发现
  12. v-1.7.0 以上已支持 SSO/OIDC
  13. v-1.9.0 以上已支持 mongodb 作为存储
  14. v-1.9.4 以上支持 OpenTelemetry🍭🍭🍭

💥 务必在使用 AgileConfig 之前仔细阅读以下文档

架构

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

客户端

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

节点、管理程序

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

数据库

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

关于高可用

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

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

有同学说你这样没什么卵用,数据库还是单点的,一旦数据库崩了,同样GG。但是数据库有数据库的高可用技术,比如mysql的binlog等等。至于数据库的高可用还是让数据库自己搞定吧。从架构上看携程的apollo数据库也是单点的。

部署服务端

初始化数据库

用户只需要手工建一个空库,所有的表在第一次启动的时候都会自动生成。目前支持sqlserver,mysql,sqlite, PostgreSql,Oracle 五种数据库。 provider对照:
sqlserver = SqlServer
mysql = MySql
sqlite = Sqlite
npgsql = PostgreSql
oracle = Oracle
mongodb = mongodb

使用服务端

运行服务端

使用 docker 运行

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" \
-p 5000:5000 \
#-v /your_host_dir:/app/db \
-d kklldog/agile_config:latest

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

  1. adminConsole 配置程序是否为管理控制台。如果为true则启用控制台功能,访问该实例会出现管理界面。
  2. db__provider 配置程序的数据库类型。目前程序支持:sqlserver,mysql,sqlite, PostgreSql,Oracle 五种数据库。
  3. db__conn 配置数据库连接串

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

使用 docker-compose 运行多节点集群, 环境变量 cluster=true 会尝试获取容器的 IP ,主动注册到节点列表:

version: '3'
services:
  agile_config_admin:
    image: "kklldog/agile_config"
    ports:
      - "15000:5000"
    networks:
      - net0
    volumes:
      - /etc/localtime:/etc/localtime
    environment:
      - TZ=Asia/Shanghai
      - adminConsole=true
      - cluster=true
      - db__provider=mysql
      - db__conn= database=configcenter;data source=192.168.0.115;User Id=root;password=mdsd;port=3306
  agile_config_node1:
    image: "kklldog/agile_config"
    ports:
      - "15001:5000"
    networks:
      - net0
    volumes:
      - /etc/localtime:/etc/localtime
    environment:
      - TZ=Asia/Shanghai
      - cluster=true
      - db__provider=mysql
      - db__conn= database=configcenter;data source=192.168.0.115;User Id=root;password=mdsd;port=3306
    depends_on:
      - agile_config_admin
  agile_config_node2:
    image: "kklldog/agile_config"
    ports:
      - "15002:5000"
    networks:
      - net0
    volumes:
      - /etc/localtime:/etc/localtime
    environment:
      - TZ=Asia/Shanghai
      - cluster=true
      - db__provider=mysql
      - db__conn= database=configcenter;data source=192.168.0.115;User Id=root;password=mdsd;port=3306
    depends_on:
      - agile_config_admin
networks:
  net0:

初始化管理员密码

第一次运行程序需要初始化超级管理员密码,超管用户名固定为 admin

节点

AgileConfig支持多节点部署,所有的节点都是平行的。为了简化部署,AgileConfig并没有单独的控制台程序,请直接使用任意一个节点作为控制台。当环境变量adminConsole=true时,该节点同时兼备数据节点跟控制台功能。为了控制台能够管理节点,所以需要在控制台配置节点的信息。

💥注意:即使是作为控制台的数据节点同样需要添加到管理程序,以便管理它。

应用

AgileConfig支持多应用程序接入。需要为每个应用程序配置名称、ID、秘钥等信息。
每个应用可以设置是否可以被继承,可以被继承的应用类似apollo的公共 namespace 的概念。公共的配置可以提取到可继承应用中,其它应用只要继承它就可以获得所有配置。
如果子应用跟被继承应用之间的配置键发生重复,子应用的配置会覆盖被继承的应用的配置。子应用可以继承多个应用,如果多个应用之间发生重复键,按照继承的顺序,后继承的应用的配置覆盖前面的应用。

配置项

配置完应用信息后可以为每个应用配置配置项。配置项支持分组。新添加的配置并不会被客户端感知到,需要手工点击“发布”才会推送给客户端。已上线的配置如果发生修改、删除、回滚操作,会实时推送给客户端。版本历史记录了配置的历史信息,可以回滚至任意版本。



客户端

控制台可以查看已连接的客户端。

使用客户端

客户端AgileConfig_Client是使用.net core standard2.0编写的一个类库,已发布到nuget,方便用户集成。

使用nuget安装客户端类库

Install-Package AgileConfig.Client

初始化客户端

以asp.net core mvc项目为例:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",

  //agile_config
  "AgileConfig": {
    "appId": "app",
    "secret": "xxx",
    "nodes": "http://localhost:5000,http://localhost:5001"//多个节点使用逗号分隔,
    "name": "client_name",
    "tag": "tag1",
    "env": "DEV"
  }
}

在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($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json"), e => Console.WriteLine($"configs {e.Action}"))
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

如果需要根据环境变量读取appsettings.{env}.json配置信息,可以通过Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")来获取。

💥注意:如果你的程序是Framework的程序请使用AgileConfig.Client4FR这个专门为Framework打造的client。使用当前版本有可能死锁造成cpu100% 的风险。

💥注意:如果节点使用nginx反代的话,需要对nginx进行配置,使其支持websocket协议,不然客户端跟节点的长连接没法建立。

读取配置

AgileConfig支持asp.net core 标准的IConfiguration,跟IOptions模式读取配置。

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private readonly IConfiguration _IConfiguration;
    private readonly IOptions<DbConfigOptions> _dbOptions;

    public HomeController(ILogger<HomeController> logger, IConfiguration configuration, IOptions<DbConfigOptions> dbOptions)
    {
        _logger = logger;
        _IConfiguration = configuration;
        _dbOptions = dbOptions;
    }

    public IActionResult Index()
    {
        return View();
    }

    /// <summary>
    /// 使用IConfiguration读取配置
    /// </summary>
    /// <returns></returns>
    public IActionResult ByIConfiguration()
    {
        var userId = _IConfiguration["userId"];
        var dbConn = _IConfiguration["db:connection"];

        ViewBag.userId = userId;
        ViewBag.dbConn = dbConn;

        return View();
    }

    /// <summary>
    /// 使用Options模式读取配置
    /// </summary>
    /// <returns></returns>
    public IActionResult ByOptions()
    {
        var dbConn = _dbOptions.Value.connection;
        ViewBag.dbConn = dbConn;

        return View("ByOptions");
    }
}

也可以通过IConfigClient来获取这个实例

public class HomeController : Controller
{
    private readonly IConfigClient _configClient

    public HomeController(IConfigClient configClient)
    {
        _configClient = configClient;
    }

    public IActionResult Index()
    {
        return View();
    }

    /// <summary>
    /// 使用IConfigClient读取配置
    /// </summary>
    /// <returns></returns>
    public IActionResult ByIConfigClient()
    {
        var userId = _configClient["userId"];
        var dbConn = _configClient["db:connection"];

        foreach (var item in _configClient.Data)
        {
            Console.WriteLine($"{item.Key} = {item.Value}");
        }

        ViewBag.userId = userId;
        ViewBag.dbConn = dbConn;

        return View();
    }
}

联系我

有什么问题可以mail我:[email protected]
也可以加qq群:1022985150

如果觉得这个项目对你有帮助可以给作者早餐加个蛋🍳🍳🍳

感谢💖💖💖

UnitySir ¥100 , 大鹏¥66.66 , 瘦草¥6.66 + 88 , ziana¥10.0 , Nullable¥9.99 , *三 ¥6.66 , HHM ¥6.66 , 微笑刺客 ¥6.66 , 飞鸟与鱼 ¥38.88, *航 ¥9.9, *啦 ¥6.66, *海 ¥6.66, Dyx 邓杨喜 ¥30 ...

还有很多同学的赞助,我就不一一列举了。当然你也可以自己修改这个文件 PR 给我。

agileconfig's People

Contributors

botao-xu avatar dependabot[bot] avatar haoqiancheng avatar harris2012 avatar incerrygit avatar jack397419 avatar kami-poi avatar kklldog avatar lungchito avatar pengqian089 avatar responsibleboy avatar sampsonye avatar tomyangok avatar wlclass avatar wwwu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

agileconfig's Issues

继承应用后相应配置的keyvalue没有继承过去

相似项目应用配置大致一样(共同的配置内容)
虽然,在新建应用时,可以选择继承应用,但发现相应配置并没有继承
image

,建议再提供导出现有应用json配置功能,让配置人员到另外一个应用中可以导入该配置;

Does the server support asp.net core 2.2

hello ,Thank you for developing this framework,I want to deploy this software on Windows server 2008 r2, but 08R2 only supports net core 2.2. A lot of net core 3.1 is referenced in the software. Can you provide a version that supports net core 2.2 ?

数据库未生成

大佬,我是下载publish分支源码进行编译使用的,配置的数据库连接,好像没有生成对应的表,不知道是不是我操作姿势不对
1631869787052_D844AAF0-C8A2-4b80-A858-84D5D851D304

缓存文件怎么配置路径

程序运行后,会在根目录生成“xxx.agileconfig.client.configs.cache”这样的缓存文件,这个文件的路径有办法配置吗?因为一方面生成在根目录,如果缓存文件多的话,看起来就很乱了,这个存储在特定的文件夹,比如根目录的cache文件夹,方便统一管理;还有就是如果是docker部署的,重新启动容器后,.cache文件就全都丢失了。

Can not start docker when passwod contains special char

System
Centos7
Docker Cmd

docker run -d \
-e adminConsole=true \
-e db:provider=sqlserver \
-e db:conn="Data Source=****;Initial Catalog=****;User ID=****;Password=!@#$%^789" \
-p 8235:5000 \
-v /etc/localtime:/etc/localtime  \
kklldog/agile_config:latest

Error

【主库】恢复检查时间:08/11/2021 10:51:47
Unhandled exception. System.TypeInitializationException: The type initializer for 'AgileConfig.Server.Data.Freesql.FreeSQL' threw an exception.
 ---> System.Exception: 【主库】状态不可用,等待后台检查程序恢复方可使用。A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 35 - An internal exception was caught)
 ---> System.Exception: 【主库】状态不可用,等待后台检查程序恢复方可使用。A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 35 - An internal exception was caught)
   at FreeSql.Internal.ObjectPool.ObjectPool`1.getFree(Boolean checkAvailable)
   at FreeSql.Internal.ObjectPool.ObjectPool`1.Get(Nullable`1 timeout)
   at FreeSql.Internal.CommonProvider.AdoProvider.ExecuteScalar(DbConnection connection, DbTransaction transaction, CommandType cmdType, String cmdText, DbParameter[] cmdParms)
   --- End of inner exception stack trace ---
   at FreeSql.Internal.CommonProvider.AdoProvider.LoggerException(IObjectPool`1 pool, PrepareCommandResult pc, Exception ex, DateTime dt, StringBuilder logtxt, Boolean isThrowException)
   at FreeSql.Internal.CommonProvider.AdoProvider.ExecuteScalar(DbConnection connection, DbTransaction transaction, CommandType cmdType, String cmdText, DbParameter[] cmdParms)
   at FreeSql.Internal.CommonProvider.AdoProvider.ExecuteScalar(String cmdText, Object parms)
   at AgileConfig.Server.Data.Freesql.EnsureTables.ExistTable(IFreeSql instance) in /src/AgileConfig.Server.Data.Freesql/EnsureTables.cs:line 44
   at AgileConfig.Server.Data.Freesql.EnsureTables.Ensure(IFreeSql instance) in /src/AgileConfig.Server.Data.Freesql/EnsureTables.cs:line 55
   at AgileConfig.Server.Data.Freesql.FreeSQL..cctor() in /src/AgileConfig.Server.Data.Freesql/FreeSQL.cs:line 18
   --- End of inner exception stack trace ---
   at AgileConfig.Server.Data.Freesql.FreeSQL.get_Instance() in /src/AgileConfig.Server.Data.Freesql/FreeSQL.cs:line 20
   at AgileConfig.Server.Service.RemoteServerNodeProxy.GetGerverNodeService() in /src/AgileConfig.Server.Service/RemoteServerNodeProxy.cs:line 38
   at AgileConfig.Server.Service.RemoteServerNodeProxy.TestEchoAsync() in /src/AgileConfig.Server.Service/RemoteServerNodeProxy.cs:line 242
   at AgileConfig.Server.Apisite.Program.Main(String[] args) in /src/AgileConfig.Server.Apisite/Program.cs:line 36

Even I use double or single quotes to handle password , it also doesn't work.
Please have a check.

注册配置项修改事件永远未触发

引入AgileConfig代码是这样的

 host.ConfigureAppConfiguration((context, config) =>
            {
              
                //new一个client实例,无参构造会从本地appsettings.json文件读取配置
                var configClient = new ConfigClient($"appsettings.{context.HostingEnvironment.EnvironmentName}.json");
                //使用AddAgileConfig配置一个新的IConfigurationSource
                config.AddAgileConfig(configClient);
                //注册配置项修改事件
                configClient.ConfigChanged += ConfigClient_ConfigChanged; 
            });


        private static void ConfigClient_ConfigChanged(ConfigChangedArg obj)
        {
            Console.WriteLine($"配置项更改!更改信息={obj.Serialize2Json()}");
        }

经观察修改正在运行的配置项后,ConfigClient_ConfigChanged没有被触发

1.4.2版本 IIS下部署 页面加载时部分静态资源404

您好:

版本:1.4.2

前提

IIS部署主程序后,AgileConfig.Server.UI 下 npm run build 后部署到 wwwroot 目录下,重启站点

现象:

输入 http://localhost:5000/ 出现404 提示“No webpage was found for the web address: http://localhost:5000/ui”
输入 http://localhost:5000/index.html 出现等待界面,仔细查看后,发现有部分资源无法加载
image

切换至 AgileConfig.Server.Apisite.exe 直接启动

输入 http://localhost:5000/ 出现404 提示“No webpage was found for the web address: http://localhost:5000/ui”
输入 http://localhost:5000/index.html 正常使用

请问这个是怎么回事呢 ?

appsettings.json中的Urls配置不生效

把appsettings.json中的配置导入到AgileConfig中,里面的Urls配置项不起作用,相同的配置在Apollo中是ok的,麻烦作者给看看到底是啥原因?

登录界面显示不了,是缺少文件么?

appsettings.Development.json
"adminConsole": true,
"preview_mode": false,
"db": {
"provider": "sqlite", //sqlite,mysql,sqlserver,npgsql,oracle
"conn": "Data Source=agile_config.db"

数据库表:
user表
1 admin 123456 2021-02-01 2021-02-01 0
super_admin super_admin 123456 2021-02-01 2021-05-01 0

配置加密问题

虽然找了历史记录你说可以 自己加密 , 但这个需求还是一个比较通用的, 建议 增加这么一个配置, 起码不能明文被抓包到吧。。

使用过程的小建议

  1. 客户端,搜索条件多加下【IP,客户端名称,应用ID】
  2. 批量刷新配置的维度【应用,IP】
  3. 强制断开之后,添加重连功能?

关于支持多数据库的建议

叶老板开发的ORM FreeSql支持数据库非常多,如果需要支持多数据库可能用这个来实现比较方便。不知道该项目更换ORM的难度,只是提个建议。感谢作者开发这么好用的工具~

使用PostgreSql数据库报错

尝试将AgileConfig部署在docker desktop中连接宿主机上的PostgreSql数据库,在进行一些编辑操作时,会产生异常,容器停止工作。

部署命令:

docker run --restart=always -e adminConsole=true -e db:provider=npgsql -e db:conn="Host=gateway.docker.internal;Port=5432;Username=user;Password=123456;Database=config" -p 5009:5000 -v /etc/localtime:/etc/localtime --name agile_config kklldog/agile_config:latest

大概有两种类型的报错:

  • System.InvalidOperationException: A transaction is already in progress; nested/concurrent transactions aren't supported.
  • Npgsql.NpgsqlOperationInProgressException: The connection is already in state 'Executing'

以下是其中一种的log输出:

warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
No XML encryptor configured. Key {d63c1e47-8e71-4f4e-8faa-b99b82db5293} may be persisted to storage in unencrypted form.
warn: Microsoft.AspNetCore.Server.Kestrel[0]
Overriding address(es) 'http://+:80'. Binding to endpoints defined in UseKestrel() instead.
Hosting environment: Production
Content root path: /app
Now listening on: http://[::]:5000
Application started. Press Ctrl+C to shut down.
info: AgileConfig.Server.Apisite.Websocket.WebsocketHandlerMiddleware[0]
Websocket client 7b7faabb-a438-40d2-be50-991561870bac Added
info: AgileConfig.Server.Apisite.Controllers.RemoteServerProxyController[0]
Request remote node http://gateway.docker.internal:5009 's action OneClientDoAction success .
info: AgileConfig.Server.Apisite.Controllers.RemoteServerProxyController[0]
Request remote node http://gateway.docker.internal:5009 's action AllClientsDoAction success .
info: AgileConfig.Server.Apisite.Controllers.RemoteServerProxyController[0]
Request remote node http://gateway.docker.internal:5009 's action OneClientDoAction success .
fail: AgileConfig.Server.Common.TinyEventBus[0]
fire event OFFLINE_CONFIG_SUCCESS error
Npgsql.NpgsqlOperationInProgressException: The connection is already in state 'Executing'
at FreeSql.UnitOfWork.Rollback()
at FreeSql.UnitOfWork.Dispose()
at FreeSql.DbContext.Dispose()
at AgileConfig.Server.Service.SysLogService.Dispose() in /src/AgileConfig.Server.Service/SysLogService.cs:line 64
at AgileConfig.Server.Service.EventRegister.b__9_11(Object param) in /src/AgileConfig.Server.Service/EventRegister.cs:line 470
at AgileConfig.Server.Common.TinyEventBus.<>c__DisplayClass6_1.b__0() in /src/AgileConfig.Server.Common/TinyEventBus.cs:line 101
fail: AgileConfig.Server.Common.TinyEventBus[0]
fire event PUBLISH_CONFIG_SUCCESS error
Npgsql.NpgsqlOperationInProgressException: A command is already in progress: INSERT INTO "agc_sys_log"("app_id", "log_type", "log_time", "log_text") VALUES(@AppId_0, @LogType_0, @LogTime_0, @LogText_0) RETURNING "id"
at FreeSql.UnitOfWork.Rollback()
at FreeSql.UnitOfWork.Dispose()
at FreeSql.DbContext.Dispose()
at AgileConfig.Server.Service.SysLogService.Dispose() in /src/AgileConfig.Server.Service/SysLogService.cs:line 64
at AgileConfig.Server.Service.EventRegister.b__9_12(Object param) in /src/AgileConfig.Server.Service/EventRegister.cs:line 494
at AgileConfig.Server.Common.TinyEventBus.<>c__DisplayClass6_1.b__0() in /src/AgileConfig.Server.Common/TinyEventBus.cs:line 101
Unhandled exception. System.InvalidOperationException: A transaction is already in progress; nested/concurrent transactions aren't supported.
at FreeSql.UnitOfWork.GetOrBeginTransaction(Boolean isCreate)
at FreeSql.DbSet1.OrmInsert() at FreeSql.DbSet1.OrmInsert(TEntity data)
at FreeSql.DbSet1.AddPrivAsync(TEntity data, Boolean isCheck) at AgileConfig.Server.Service.SysLogService.AddSysLogAsync(SysLog log) in /src/AgileConfig.Server.Service/SysLogService.cs:line 32 at AgileConfig.Server.Service.RemoteServerNodeProxy.AppClientsDoActionAsync(String address, String appId, WebsocketAction action) in /src/AgileConfig.Server.Service/RemoteServerNodeProxy.cs:line 113 at AgileConfig.Server.Service.EventRegister.<RegisterWebsocketAction>b__8_3(Object param) in /src/AgileConfig.Server.Service/EventRegister.cs:line 176 at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__139_1(Object state) at System.Threading.QueueUserWorkItemCallback.<>c.<.cctor>b__6_0(QueueUserWorkItemCallback quwi) at System.Threading.ExecutionContext.RunForThreadPoolUnsafe[TState](ExecutionContext executionContext, Action1 callback, TState& state)
at System.Threading.QueueUserWorkItemCallback.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()

界面调整小建议

1、从关联应用继承的配置项显示出来
2、配置项按分组显示
对于配置项比较多的项目还是很有用的,方便管理配置项

建议环境变量参数不要用冒号等特殊字符

在一些K8S管理工具下,特殊字符不被支持
Validation failed in API: Deployment.apps "agile-config" is invalid: [spec.template.spec.containers[0].env[2].name: Invalid value: "db:conn": a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit (e.g. 'my.env-name', or 'MY_ENV.NAME', or 'MyEnvName1', regex used for validation is '[-._a-zA-Z][-.a-zA-Z0-9]*'), spec.template.spec.containers[0].env[3].name: Invalid value: "db:provider": a valid environment variable name must consist of alphabetic characters, digits, '', '-', or '.', and must not start with a digit (e.g. 'my.env-name', or 'MY_ENV.NAME', or 'MyEnvName1', regex used for validation is '[-._a-zA-Z][-._a-zA-Z0-9]*')]

关于发布的问题

我自己下载了源代码后,修改完appsetting的数据库配置后,使用AgileConfig.Server.Apisite能启动项目,但是想发布到本地使用发现发布的程序无法启动。请问这个项目想本地发布该怎么操作

控制台页面404

下载源码。还原nuget,配置数据库正常,设置AgileConfig.Server.Apisite 为启动项,调试发现跳转

http://localhost:5000/ui#/user/initpassword
页面出不来。

配置如下:

{
"Logging": {
"LogLevel": {
"Default": "Information",
"System": "Warning",
"Microsoft": "Warning"
}
},
"adminConsole": true,
"preview_mode": false,
"db": {
"provider": "sqlserver", //sqlite,mysql,sqlserver,npgsql,oracle
//"conn": ""
"conn": "Data Source=xxxxx;User ID=sa;Password=11223Initial Catalog=ApolloConfig;Pooling=true;Min Pool Size=1"
//"conn": "Persist Security Info = False; User ID =dev; Password =dev@123; Initial Catalog =agile_config; Server =."
},
"JwtSetting": {
"SecurityKey": "dfasf343453fsdfa,./,./sdfasf34r3hfhfdb", // 密钥
"Issuer": "agileconfig.admin", // 颁发者
"Audience": "agileconfig.admin", // 接收者
"ExpireSeconds": 86400 // 过期时间
}
}

关于配置项相关的疑问

image

目前是值支持键值对这种形式吗? 比如我想在客户端里读出一个配置节点的对象,应该怎么操作呢?

[BUG] release-1.4.2 角色权限问题

版本: 1.4.2
数据库: sqlite
现象: 用新建的账号发布配置变更,提示发布失败,并跳转至登陆界面
复现步骤:
点击【用户】菜单,【添加】用户按钮,输入用户名称与密码,选择角色为“管理员”
点击【应用】菜单,选择【配置】按钮,赋予新建用户为管理员
点击【应用】菜单,选择【授权】按钮,赋予新建用户,修改权,发布权
再次选择【授权】按钮,确认已授权
退出,使用新用户登录
修改配置功能正常
发布配置功能异常,提示发布失败,并跳转至登陆界面

客户端数量一直为0

客户端可以正常读取服务端配置数据,但是UI界面一直显示0,没有客户端数据,是哪里需要配置吗?

另外一个问题是:查看了本地缓存,只有其中一个应用的缓存,其他应用未发现缓存文件,不知道这个是否正常?

docker 环境错误

错误信息:

When ::ffff:221.237.187.12 request /admin/InitPassword error , but not handled .
 The type initializer for 'AgileConfig.Server.Data.Freesql.FreeSQL' threw an exception. 
    at AgileConfig.Server.Data.Freesql.FreeSQL.get_Instance() in /src/AgileConfig.Server.Data.Freesql/FreeSQL.cs:line 20
   at AgileConfig.Server.Data.Freesql.ServiceCollectionExt.<>c.<AddFreeSqlDbContext>b__0_0(DbContextOptionsBuilder options) in /src/AgileConfig.Server.Data.Freesql/ServiceCollectionExt.cs:line 12
   at Microsoft.Extensions.DependencyInjection.FreeSqlDbContextDependencyInjection.<>c__DisplayClass0_0.<AddFreeDbContext>b__0(IServiceProvider sp)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.GetService(IServiceProvider sp, Type type, Type middleware)
   at lambda_method(Closure , Object , HttpContext , IServiceProvider )
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass4_1.<UseMiddleware>b__2(HttpContext context)
   at Microsoft.AspNetCore.WebSockets.WebSocketMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.EvaluateAndApplyPolicy(HttpContext context, CorsPolicy corsPolicy)
   at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.Invoke(HttpContext context, ICorsPolicyProvider corsPolicyProvider)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass4_1.<UseMiddleware>b__2(HttpContext context)
   at AgileConfig.Server.Apisite.UIExtension.ReactUIMiddleware.Invoke(HttpContext context) in /src/AgileConfig.Server.Apisite/UIExtension/ReactUIMiddleware.cs:line 127
   at AgileConfig.Server.Common.ExceptionHandlerMiddleware.Invoke(HttpContext context) in /src/AgileConfig.Server.Common/ExceptionHandlerMiddleware.cs:line 27
url: http://*/admin/InitPassword action: 
The type initializer for 'AgileConfig.Server.Data.Freesql.FreeSQL' threw an exception.

这是什么错误,连不上数据库?使用sqlite也不行

镜像文件过大(1.59GB),建议采用如下方式构建以缩减镜像大小,修改后为281MB

修改方式:

  1. 修改Dockerfile内容如下,并将Dockerfile移动到AgileConfig.Server.Apisite项目下,并修改该文件的属性“Copy to output Directory”为“Copy always”.
    FROM mcr.microsoft.com/dotnet/aspnet:3.1-buster-slim AS base
    WORKDIR /app
    EXPOSE 5000
    COPY . /app
    ENTRYPOINT ["dotnet", "AgileConfig.Server.Apisite.dll"]
  2. 发布项目AgileConfig.Server.Apisite,发布目录如“\AgileConfigmaster\AgileConfig.Server.Apisite\bin\Release\netcoreapp3.1\publish”
  3. 切换到发布目录,执行构建命令"docker build -t agile_config ."

修改前镜像大小:
image
修改后镜像大小:
image

你这开源也太潦草了把

1.关于项目结构希望还是能够描述清楚
2.关于前后端分离,建议两个项目,一个前端一个后端.
3.关于发行版本,可以直接编译出来
4.前后端具体的编译也可以稍微介绍下.

k8s中pod环境变量问题

报错提示只允许字母数字和一些字符串 作者能不能改一下最新版本镜像的环境变量名
报错信息
Deployment.apps "agile-v1" is invalid: [spec.template.spec.containers[0].env[1].name: Invalid value: "db:provide": a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit (e.g. 'my.env-name', or 'MY_ENV.NAME', or 'MyEnvName1', regex used for validation is '[-._a-zA-Z][-._a-zA-Z0-9]*'), spec.template.spec.containers[0].env[2].name: Invalid value: "db:conn": a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit (e.g. 'my.env-name', or 'MY_ENV.NAME', or 'MyEnvName1', regex used for validation is '[-._a-zA-Z][-._a-zA-Z0-9]*')]

PostgreSql的连接串怎么写?

一直提示
【主库】状态不可用,等待后台检查程序恢复方可使用。连接字符串错误
貌似 Data Source=10.2.27.212;Port=5432;User ID=postgre;Password=postgre;Database=AgileConfig;

这种写法不行...

建议添加环境配置和多重继承的支持

建议添加环境配置和多重继承的支持

1. 环境配置

当前没有环境的概念,支持环境的配置后可以很方便地在不同的部署环境下切换配置;
可分开发环境、测试环境和生产环境,类似于 appsettings.json,appsettings.Development.json的关系。

2. 多重继承

当前只有两个层级,支持多重继承可以提高配置的复用。
子配置可以继承父配置,孙子配置可以继承子配置等,没有继承层级的限制,或者最多能支持到3~5层配置。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.