使用其它的配置服务

Nebula是一个基于 .NET 技术的开发框架体系,核心特色是【支持SaaS多租户】、【支持微服务开发】和【实时可观测能力】。

这是Nebula的设计目标。

为了实现这些能力,Nebula的许多功能都依赖于 自带的 配置服务,例如下面这些API:

  • ConfigClient.Instance.GetSetting(string name)
  • Settings.GetSetting(string name)
  • ConfigFile.GetFile(string name)
  • DbConnManager.CreateMaster()
  • DbConnManager.CreateAppDb(string name)
  • DbConnManager.CreateTenant(string tenantId)
  • 各种Client:RabbitMQ/Redis/InfluxDB/Mail/IM/.....

考虑到以下二种场景:

它们可能并不会启用Nebula自带的 配置服务,甚至使用第三方的配置服务,例如:Nacos

本文将介绍如何解决这个问题:使用其它的配置服务之后,以上API仍能正常工作。



理解配置服务

配置服务只有一个功能:统一管理的各种远程配置参数:

  • 全局配置参数
    • 读取方式:Settings.GetSetting(string name)
  • 数据库连接参数
    • 读取方式:DbConnManager.CreateAppDb(string name)
  • 远程独立配置文件
    • 读取方式:ConfigFile.GetFile(string name)
  • 远程配置文件(xxx.App.config, xxx.Log.config)
    • 读取方式:Nebula内部调用

为了实现配置服务的替换,必须将以上参数转成 第三方配置服务能接受的方式:

  • 所有 全局配置参数:变成一个配置文件,即 key=value 的数组形式,再做个JSON/XML 序列化即可。
  • 所有 数据库连接参数:同上处理
  • 远程独立配置文件:保持不变
  • 远程配置文件:保持不变

然后将这些文件内容存储在 第三方配置服务。



实现思路

ConfigClient是所有访问配置服务的入口类,只要把它的行为替换就可以了。

Nebula将各配置种读取操作抽象了一个接口:IConfigClient

为了能替代Nebula自带的配置服务,我们有2种方法

  • 使用内置的工具类:MemoryConfig,因为内存中的数据总是优先查找的。
  • 实现IConfigClient接口,然后调用 ConfigClient.Instance.SetClient 来注册它

1,实现IMoonClient接口,这是一种最更灵活通用的方案。

  • 优点:允许你来决定所有的替换细节
  • 缺点:需要时间开发

2,MemoryConfig 是一种简单且内置的实现,可以理解为:

  • 将程序所需要的配置参数直接放在内存中
  • 当需要访问配置服务时,Nebula会自动切换到内存中获取它们

它提供以下方法来接收数据:

public static void AddSetting(string name, string value)
public static void AddDbConfig(string name, DbConfig config)
public static void AddFile(string name, string fileText)
public static void SetAppConfig(string xml)
public static void SetLogConfig(string xml)

本文将介绍MemoryConfig这种方式来实现。



加载配置参数

有了前面的步骤,所有配置参数都存储在第三方配置服务中,程序就可以读取它们。

如何从第三方配置服务中读取参数,请参考相关文档,此处忽略!


在程序启动时,先将本程序所需的各种参数读取到,然后调用MemoryConfig相关方法即可,例如:

public override void PreNebulaInit()
{
    NacosConfig config = LocalSetting.GetSetting<NacosConfig>("NacosConfig");
    NacosClient client = new NacosClient(config);

    // 假设用应用程序的名称做命名空间
    string @namespace = AppStartup.RuntimeStatus.ApplicationName;


    // 加载 全局配置参数
    string settings = client.GetValue(@namespace, "settings.json");
    settings.FromJson<List<NameValue>>().ForEach(x => MemoryConfig.AddSetting(x.Name, x.Value));

    // 加载 数据库连接参数
    string conns = client.GetValue(@namespace, "db_conns.json");
    conns.FromJson<List<DbConfig>>().ForEach(x => MemoryConfig.AddDbConfig(x.Name, x));

    // 加载 远程独立配置文件
    string file1 = client.GetValue(@namespace, "file1.xml");
    MemoryConfig.AddFile("file1", file1);

    // 加载 远程配置文件
    string appConfig = client.GetValue(@namespace, "App.Config");
    MemoryConfig.SetAppConfig(appConfig);
}