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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM