zoukankan      html  css  js  c++  java
  • ASP.NET Core集成Nacos配置中心之适配多格式配置

    前言

    默认情况下,用nacos-sdk-csharp集成ASP.NET Core的配置系统,是基于JSON格式的数据。

    随着业务系统的多样化,可能用的配置格式也是各有千秋的。有的会用yaml/yml,有的会用ini,有的会用xml,等等。

    那么如果我们存在nacos里面的配置数据是非JSON格式的,我们要怎么去适配呢?

    老黄在下面为大家一一解答,主要从两个问题点来切入。

    1. 集成yaml/yml格式的的配置
    2. 定制不同格式的parser

    集成yaml/yml格式的的配置

    目前最新的稳定版及预览版除了默认的JSON外,还支持yaml/ymlini两种格式,这里就以yaml/yml为例来说明。

    这里会创建一个WebAPI项目来演示,创建好项目后,安装下面两个nuget包

    <PackageReference Include="nacos-sdk-csharp-unofficial.Extensions.Configuration" Version="0.5.0" />
    <PackageReference Include="nacos-sdk-csharp-unofficial.YamlParser" Version="0.5.0" />
    

    一个是.NET Core的集成包,一个是yaml格式的数据解析包。

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }
    
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((context, builder) =>
                 {
                     var c = builder.Build();
    
                     // read configuration from config files, and the data type is yaml/yml
                     builder.AddNacosConfiguration(
                     c.GetSection("NacosConfig"),
                     Nacos.YamlParser.YamlConfigurationStringParser.Instance);
                 })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
    

    还要先配置nacos相关的内容。

    {
      "NacosConfig": {
        "Optional": false,
        "DataId": "yamlconfigdemo",
        "Group": "",
        "Tenant": "f47e0ae1-982a-4a64-aea3-52506492a3d4",
        "ServerAddresses": [ "http://localhost:8848/" ],
        "UserName": "",
        "Password": "",
        "AccessKey": "",
        "SecretKey": "",
        "EndPoint": ""
      }
    }
    

    后面是定义配置的映射类,这一步是可选的,目的是为了使用配置的时候可以点出来。

    public class AppSettings
    {
        public string Str { get; set; }
    
        public int Num { get; set; }
    
        public List<int> Arr { get; set; }
    
        public SubObj SubObj { get; set; }
    }
    
    public class SubObj
    {
        public string a { get; set; }
    }
    

    要映射,别忘了在Startup里面加这一句。

    services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
    

    然后是控制器读配置。

    [ApiController]
    [Route("api/[controller]")]
    public class ConfigController : ControllerBase
    {
        private readonly ILogger<ConfigController> _logger;
        private readonly IConfiguration _configuration;
        private readonly AppSettings _settings;
        private readonly AppSettings _sSettings;
        private readonly AppSettings _mSettings;
    
        public ConfigController(
            ILogger<ConfigController> logger,
            IConfiguration configuration,
            IOptions<AppSettings> options,
            IOptionsSnapshot<AppSettings> sOptions,
            IOptionsMonitor<AppSettings> _mOptions
            )
        {
            _logger = logger;
            _configuration = configuration;
            _settings = options.Value;
            _sSettings = sOptions.Value;
            _mSettings = _mOptions.CurrentValue;
        }
    
        [HttpGet]
        public string Get()
        {
            string id = Guid.NewGuid().ToString("N");
    
            _logger.LogInformation($"============== begin {id} =====================");
    
            var conn = _configuration.GetConnectionString("Default");
            _logger.LogInformation($"{id} conn = {conn}");
    
            var version = _configuration["version"];
            _logger.LogInformation($"{id} version = {version}");
    
            var str1 = Newtonsoft.Json.JsonConvert.SerializeObject(_settings);
            _logger.LogInformation($"{id} IOptions = {str1}");
    
            var str2 = Newtonsoft.Json.JsonConvert.SerializeObject(_sSettings);
            _logger.LogInformation($"{id} IOptionsSnapshot = {str2}");
    
            var str3 = Newtonsoft.Json.JsonConvert.SerializeObject(_mSettings);
            _logger.LogInformation($"{id} IOptionsMonitor = {str3}");
    
            _logger.LogInformation($"===============================================");
    
            return "ok";
        }
    }
    

    因为这个配置不是可选的,所以在启动应用之前,要添加下面的配置在nacos里面,不然启动是会报错的。

    具体如下:

    ConnectionStrings: 
      Default: Server=127.0.0.1;Port=3306;Database=demo;User Id=root;Password=123456; 
    version: 测试version
    AppSettings: 
      Str: val
      num: 1
      arr: 
      - 1
      - 2
      - 3
      subobj: 
        a: b
    

    运行并访问 http://localhost:5000/api/config,我们可以看到程序的日志输出,是能正常拿到配置的数据的。

    这也就是说,我们的程序已经可以正常读取Yaml格式的配置了。

    再来看看修改之后能不能及时获取到最新的配置。

    修改后再访问一次。

    从结果看,也是能及时获取到最新的配置。

    就目前来说,JSON,yaml/yml,ini格式的数据应该能满足60%~80%左右的需求,如果遇到一个“新格式”,我们要怎么做呢?

    下面来具体看看。

    定制自己的parser

    在Nacos客户端里面,定义了一个名为INacosConfigurationParser的接口,具体如下:

    public interface INacosConfigurationParser
    {
        IDictionary<string, string> Parse(string input);
    }
    

    这个接口里面也只有一个方法,这个方法的目的就是把字符串类型的配置,转化成一个键值对,从而让.NET Core的配置系统能够识别出来。

    下面来个不完整的例子:

    public class XmlConfigurationStringParser : INacosConfigurationParser
    {
        public static XmlConfigurationStringParser Instance = new XmlConfigurationStringParser();
    
        public IDictionary<string, string> Parse(string input)
        {
            // 具体的解析逻辑
        }
    }
    

    实现好自己的parser之后,就可以在Program里面去指定这个parser了。

    // builder.AddNacosConfiguration(
    // c.GetSection("NacosConfig"),
    // Nacos.YamlParser.YamlConfigurationStringParser.Instance);
    
    builder.AddNacosConfiguration(
    c.GetSection("NacosConfig"),
    XmlConfigurationStringParser.Instance);
    

    这个时候就会使用XmlConfigurationStringParser去解析配置了。

    总结

    有了这个特性之后,基本上只要能把对应格式的数据正常解析,就能很好的集成到ASP.NET Core里面了。

    如果nacos控制台里面的配置格式没有我们需要的,我们可以直接配置成TEXT格式,这个是不影响我们使用的,只是显示的时候没那么直观。

    最后,如果您对 nacos-sdk-csharp 这个项目感兴趣,可以加入我们一起来完善哟,issue,PR都ok的。

    nacos 2.x版本可能会引用grpc或rsocket进行长链接的改造,到时sdk这边可能也会是一个比较有意思的改进。

    项目地址:

    https://github.com/nacos-group/nacos-sdk-csharp

  • 相关阅读:
    BZOJ-1016 最小生成树计数
    BZOJ-1003 物流运输
    BZOJ-1009 GT考试
    【NOIP2014】伤感·伤感·伤感
    BZOJ-1033 杀蚂蚁
    NOIP一系列模拟赛小结
    2014·NOIP 新的历程,新的开始
    35. Search Insert Position
    29. Divide Two Integers
    28. Implement strStr()
  • 原文地址:https://www.cnblogs.com/catcher1994/p/13761941.html
Copyright © 2011-2022 走看看