配置中心

我们的配置中心基于 consul kv 和 开源项目 Winton.Extensions.Configuration.Consul 实现。

分布式配置中心最核心的需求就是当配置发生更变后可以自动的通知到应用程序,并完成配置更新。
大部分基于 consul 实现的配置中心都是使用了 consul 提供的 kv 读取 api,并通过 http 长链接的形式来实时获取最新配置内容。
详细原理请参考 github 源码。

dotnet core 集成配置中心

  1. 添加项目引用

    dotnet add package Winton.Extensions.Configuration.Consul
    
  2. 环境变量中增加 consul 读取地址 “CONSUL_URL”请注意运行环境环境变量注入方式。

    {
      "env": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "SERVICE_NAME": "product",
        "CONSUL_URL": "http://127.0.0.1:8500/"
      }
    }
    
  3. Program.cs 中增加配置的自定义配置源。配置相关请参考微软 官方文档

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }
    
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host
            .CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, builder) =>
            {
                builder.AddEnvironmentVariables();
                // 环境变量中读取 consul api 地址
                var consulUrl = System.Environment.GetEnvironmentVariable("CONSUL_URL");
                if (!string.IsNullOrEmpty(consulUrl))
                {
                    // 指定从根开始的 kv 存储的 key
                    builder.AddConsul("stage.product.config", opt =>
                    {
                        opt.ConsulConfigurationOptions = (consulConfig) =>
                        {
                            consulConfig.Address = new Uri(consulUrl);
                        };
                        opt.Optional = true;
                        opt.ReloadOnChange = true;
                        opt.OnLoadException = exceptionContext => { exceptionContext.Ignore = true; };
                    });
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
    
  4. consul 服务端增加配置内容 json 格式

    consul-config-center

  5. dotnet core 程序使用

    定义配置内容数据模型

    /// <summary>
    /// 定义配置
    /// </summary>
    public class ProductConfig
    {
        public int MaxCnt { get; set; } = 100;
    }
    

    通过 IConfiguration 接口获取最新配置内容,此时,当 consul 的配置发生更新后,应用程序将自动获取到最新的配置内容。

    [ApiController]
    public class ApiController : ControllerBase
    {
        private readonly IConfiguration _config;
        public ApiController(IConfiguration config)
        {
            _config = config;
        }
    
        [HttpGet]
        [Route("/api/config")]
        [AllowAnonymous]
        public async Task<IActionResult> GetConfig()
        {
            var config = _configuration.Get<ProductConfig>();
            return await Task.FromResult( new JsonResult(config));
        }
    }