Nacos配置中心+ASP.NET Core

語言: CN / TW / HK

Nacos配置中心

nacos 是一個構建雲原生應用的動態服務發現、配置管理和服務管理平臺。。

原始碼已上傳至 github

配置管理

asp.net core中所有的配置項,如appsetting.json進行集中管理,支援熱載入,支援服務發現。

安裝請參考: https://nacos.io/zh-cn/docs/quick-start.html

開始

  • windows 進入nacos的bin目錄,或把目錄 D:\work\tools\nacos\bin (我本地)配置到環境變數中的Path中。

即可在任意位置,執行命令

startup.cmd -m standalone
  • standalone代表著單機模式執行,非叢集模式
C:\WINDOWS\system32>startup.cmd -m standalone
"nacos is starting with standalone"

         ,--.
       ,--.'|
   ,--,:  : |                                           Nacos 2.0.3
,`--.'`|  ' :                       ,---.               Running in stand alone mode, All function modules
|   :  :  | |                      '   ,'\   .--.--.    Port: 8848
:   |   \ | :  ,--.--.     ,---.  /   /   | /  /    '   Pid: 14504
|   : '  '; | /       \   /     \.   ; ,. :|  :  /`./   Console: http://192.168.0.10:8848/nacos/index.html
'   ' ;.    ;.--.  .-. | /    / ''   | |: :|  :  ;_
|   | | \   | \__\/: . ..    ' / '   | .; : \  \    `.      https://nacos.io
'   : |  ; .' ," .--.; |'   ; :__|   :    |  `----.   \
|   | '`--'  /  /  ,.  |'   | '.'|\   \  /  /  /`--'  /
'   : |     ;  :   .'   \   :    : `----'  '--'.     /
;   |.'     |  ,     .-./\   \  /            `--'---'
'---'        `--`---'     `----'

預設執行在8848埠

必做

登入後,開啟 名稱空間 ->新建名稱空間->

  • 名稱空間ID :這裡填, cs-test ,注意下方的配置項Namespace請填寫此值。
  • 名稱空間名: 這個只是用於展示區分,填 cs-test ,建議直接和名稱空間id相同即可。
  • 描述: :這個隨便填

Nacos+Console

新建一個控制檯專案

引入包

<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
<PackageReference Include="nacos-sdk-csharp" Version="1.2.2" />
static IHost AppStartup()
{
    var host = Host.CreateDefaultBuilder()
                .ConfigureServices((context, services) =>
                {
                    ConfigureServices(context, services);
                    services.AddTransient<App>();
                })
                .ConfigureAppConfiguration((host, config) =>
                {

                })
                .Build(); // Build the Host

    return host;
}

配置 nacos 的服務

static void ConfigureServices(HostBuilderContext context,IServiceCollection services)
{
    services.AddNacosV2Config(x =>
    {
        x.ServerAddresses = new System.Collections.Generic.List<string> { "http://localhost:8848/" };
        x.EndPoint = "";
        x.Namespace = "cs-test";

        /*x.UserName = "nacos";
       x.Password = "nacos";*/

        // swich to use http or rpc
        x.ConfigUseRpc = true;
    });

    services.AddNacosV2Naming(x =>
    {
        x.ServerAddresses = new System.Collections.Generic.List<string> { "http://localhost:8848/" };
        x.EndPoint = "";
        x.Namespace = "cs-test";

        /*x.UserName = "nacos";
       x.Password = "nacos";*/

        // swich to use http or rpc
        x.NamingUseRpc = true;
    });
}

呼叫

var host = AppStartup();
var service = ActivatorUtilities.CreateInstance<App>(host.Services);
await service.RunAsync(args);

App.cs檔案配置

public class App
{
    private readonly ILogger<App> _logger;
    private readonly INacosConfigService _ns;
    public App(ILogger<App> logger, INacosConfigService ns)
    {
        _logger = logger;
        _ns = ns;
    }

    public async Task RunAsync(string[] args)
    {
        await PublishConfig(_ns);
        await GetConfig(_ns);
        await RemoveConfig(_ns);
    }

    static async Task PublishConfig(INacosConfigService svc)
    {
        var dataId = "demo-dateid";
        var group = "demo-group";
        var val = "test-value-" + DateTimeOffset.Now.ToUnixTimeSeconds().ToString();

        await Task.Delay(500);
        var flag = await svc.PublishConfig(dataId, group, val);
        Console.WriteLine($"======================釋出配置結果,{flag}");
    }

    static async Task GetConfig(INacosConfigService svc)
    {
        var dataId = "demo-dateid";
        var group = "demo-group";

        await Task.Delay(500);
        var config = await svc.GetConfig(dataId, group, 5000L);
        Console.WriteLine($"======================獲取配置結果,{config}");
    }

    static async Task RemoveConfig(INacosConfigService svc)
    {
        var dataId = "demo-dateid";
        var group = "demo-group";

        await Task.Delay(500);
        var flag = await svc.RemoveConfig(dataId, group);
        Console.WriteLine($"=====================刪除配置結果,{flag}");
    }
}

f5執行後可看到輸出如下內容

======================釋出配置結果,True
======================獲取配置結果,test-value-1637000754
=====================刪除配置結果,True

我們把 await RemoveConfig(_ns); 這行刪除,即可在nacos的網站上看到資訊。

配置管理 -選 cs-test ,可以看到 Data Id為demo-dateidGroupdemo-group 的一行資料,點選行內的編輯即可看到具體資訊。

Nacso+Asp.NET Core

新增包

<PackageReference Include="nacos-sdk-csharp.AspNetCore" Version="1.2.2" />
<PackageReference Include="nacos-sdk-csharp.Extensions.Configuration" Version="1.2.2" />

在Program中配置服務

builder.Host.ConfigureAppConfiguration((context, builder) =>
        {
            var c = builder.Build();

            // 從配置檔案讀取Nacos相關配置
            // 預設會使用JSON解析器來解析存在Nacos Server的配置
            builder.AddNacosV2Configuration(c.GetSection("NacosConfig"));
            // 也可以按需使用ini或yaml的解析器
            // builder.AddNacosV2Configuration(c.GetSection("NacosConfig"), Nacos.IniParser.IniConfigurationStringParser.Instance);
            // builder.AddNacosV2Configuration(c.GetSection("NacosConfig"), Nacos.YamlParser.YamlConfigurationStringParser.Instance);
        });

appsetting.json 配置

{
    "NacosConfig": {
        "Listeners": [
            {
                "Optional": false,
                "DataId": "common",
                "Group": "DEFAULT_GROUP"
            },
            {
                "Optional": false,
                "DataId": "demo",
                "Group": "DEFAULT_GROUP"
            }
        ],
        "Namespace": "cs-test",
        "ServerAddresses": [
            "http://localhost:8848/"
        ],
        "UserName": "nacos",
        "Password": "nacos",
        "AccessKey": "",
        "SecretKey": "",
        "EndPoint": "",
        "ConfigFilterAssemblies": [
        ],
        "ConfigFilterExtInfo": ""
    }
}

在上面我們可以看到 DataIdcommon 的、我們去管理端UI,名稱空間為 cs-test 新增一個配置

新增二個配置項

  • Data ID:common
  • Group:DEFAULT_GROUP
  • 配置內容:選擇json。
{
    "UserInfo":{
        "Name":"luo",
        "Sex":"Boy",
        "Age":99
    },
    "commonkey":"commonkey_value_值"
}
  • Data ID:demo
  • Group:DEFAULT_GROUP
  • 配置內容:選擇json。
{
    "demokey":"demo_value_值"
}

那我們如何獲取的這麼一個json值和demokey中的值呢。

我們新增一個類

public class UserInfo
    {
        public string Name { get; set; }
        public string Sex { get; set; }
        public int Age { get; set; }
    }

在預設的控制器注入 IConfiguration ,像從appsettings.json中獲取資料一樣,可直接取出來。

private readonly ILogger<ConfigController> _logger;
    private readonly IConfiguration _configuration;

    public ConfigController(ILogger<WeatherForecastController> logger, IConfiguration configuration)
    {
        _logger = logger;
        _configuration = configuration;
    }

    [HttpGet("getconfig")]
    public UserInfo GetConfig()
    {
        var userInfo1 = _configuration.GetSection("UserInfo").Get<UserInfo>();
        var commonvalue = _configuration["commonkey"];
        var demovalue = _configuration["demokey"];
        _logger.LogInformation("commonkey:" + commonvalue);
        _logger.LogInformation("demokey:" + demovalue);
        return userInfo1;
    }

會輸出如下內容

info: NacosApi.Controllers.WeatherForecastController[0]
      commonkey:commonkey_value_值
info: NacosApi.Controllers.WeatherForecastController[0]
      demokey:demo_value_值

並在介面上返回 UserInfo的資訊。

{
  "name": "luo",
  "sex": "Boy",
  "age": 99
}

注意

  • 當二個 DataId 中配置的json,包含相同的Key時,實際會依後面的Key中值為準。順序以appsetting.json中的配置Listeners的陣列順序為依據。

當然我們通過強型別繫結 UserInfo ,在 Program 配置服務

builder.Services.Configure<UserInfo>(builder.Configuration.GetSection("UserInfo"));
public ConfigController(ILogger<ConfigController> logger,
        IConfiguration configuration,
        IOptions<UserInfo> options1,
        IOptionsSnapshot<UserInfo> options2,
        IOptionsMonitor<UserInfo> options3
    )
{
    _logger = logger;
    _configuration = configuration;
    _user1 = options1.Value;
    _user2 = options2.Value;
    _user3 = options3.CurrentValue;
}

[HttpGet]
public string Get()
{
    string id = Guid.NewGuid().ToString("N");

    _logger.LogInformation($"============== begin {id} =====================");

    var str1 = Newtonsoft.Json.JsonConvert.SerializeObject(_user1);
    _logger.LogInformation($"{id} IOptions = {str1}");

    var str2 = Newtonsoft.Json.JsonConvert.SerializeObject(_user2);
    _logger.LogInformation($"{id} IOptionsSnapshot = {str2}");

    var str3 = Newtonsoft.Json.JsonConvert.SerializeObject(_user3);
    _logger.LogInformation($"{id} IOptionsMonitor = {str3}");

    _logger.LogInformation($"===============================================");

    return "ok";
}

當然輸出是一模一樣的。我們在介面上再次調整下資料

info: NacosApi.Controllers.ConfigController[0]
      7bafb7f9cd2a46ec95324e38d01048aa IOptions = {"Name":"luo","Sex":"Boy","Age":99}
info: NacosApi.Controllers.ConfigController[0]
      7bafb7f9cd2a46ec95324e38d01048aa IOptionsSnapshot = {"Name":"luo","Sex":"Boy","Age":99}
info: NacosApi.Controllers.ConfigController[0]
      7bafb7f9cd2a46ec95324e38d01048aa IOptionsMonitor = {"Name":"luo","Sex":"Boy","Age":99}

只有 IOptions<UserInfo> 不會變化,其他是會跟著變化的。

info: NacosApi.Controllers.ConfigController[0]
      604d8db7b0ad48ccbc64c3ccd06eb524 IOptions = {"Name":"luo","Sex":"Boy","Age":99}
info: NacosApi.Controllers.ConfigController[0]
      604d8db7b0ad48ccbc64c3ccd06eb524 IOptionsSnapshot = {"Name":"abc","Sex":"Boy","Age":99}
info: NacosApi.Controllers.ConfigController[0]
      604d8db7b0ad48ccbc64c3ccd06eb524 IOptionsMonitor = {"Name":"abc","Sex":"Boy","Age":99}

Docker 安裝 Nacos

1.拉取映象

docker pull nacos/nacos-server

2、建立本地的對映檔案,application.properties,

mkdir -p  /root/nacos/logs /root/nacos/conf

配置資料庫

vim /root/nacos/conf/application.properties
  • application.properties
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://ip:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=userid
db.password=userpassword

下面通過配置來暴露除了/shutdown之外的所有端點。下面通過配置來暴露除了/shutdown之外的所有端點

management.endpoints.web.exposure.include=*

執行容器:使用 standalone 模式並開放8848埠,並對映配置檔案和日誌目錄,資料庫在application.properties中配置

docker run -d -p 8848:8848 -p 9848:9848 -p 9555:9555 -e MODE=standalone -e PREFER_HOST_MODE=hostname -v /root/nacos/logs:/home/nacos/logs -v /root/nacos/conf/application.properties:/home/nacos/conf/application.properties --restart always --name nacos nacos/nacos-server

其中-v 指定對映配置。左側為linux檔案,右側為docker目錄

更多指令

啟動容器

docker start 容器id
或者
docker start nacos

關閉容器

docker stop nacos

部落格