Skip to content

Files

Latest commit

author
Calvin
Jul 29, 2022
7f6b7a7 · Jul 29, 2022

History

History
This branch is 28 commits ahead of, 81 commits behind apolloconfig/apollo.net:main.

Apollo.ConfigurationManager

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
Nov 18, 2021
Jul 29, 2022
Jul 29, 2022
Apr 21, 2022
Apr 21, 2022
Nov 19, 2021
Nov 25, 2021
May 19, 2022
May 19, 2022
Nov 19, 2021
Nov 19, 2021
Nov 26, 2021
May 19, 2022
Jun 22, 2022
Apr 21, 2022

# 一、准备工作

如果想将传统的config配置(如web.config)转成json配置,可以使用config2json工具

1.1 环境要求

1.2 必选设置

Apollo客户端依赖于AppIdEnvironment等环境信息来工作,所以请确保阅读下面的说明并且做正确的配置:

由于Long Poll会占用连接数量,因此可能需要配置最大连接数

仅.NET Framework需要配置

1.2.1 AppId

AppId是应用的身份信息,是从服务端获取配置的一个重要信息。

请确保在app.config或web.config有AppID的配置,其中内容形如:

<?xml version="1.0"?>
<configuration>
    <appSettings>
        <!-- Change to the actual app id -->
        <add key="Apollo:AppId" value="SampleApp"/>
    </appSettings>
</configuration>

注:Apollo:AppId是用来标识应用身份的唯一id,格式为string。

1.2.2 Environment

Apollo支持应用在不同的环境有不同的配置,所以Environment是另一个从服务器获取配置的重要信息。

请确保在app.config或web.config有AppID的配置,其中内容形如:

<?xml version="1.0"?>
<configuration>
    <appSettings>
        <add key="Apollo:Env" value="Dev" />
    </appSettings>
</configuration>

目前,env支持以下几个值(大小写不敏感):

  • DEV
    • Development environment
  • FAT
    • Feature Acceptance Test environment
  • UAT
    • User Acceptance Test environment
  • PRO
    • Production environment

1.2.3 服务地址

Apollo客户端针对不同的环境会从不同的服务器获取配置,所以请确保在app.config或web.config正确配置了服务器地址(Apollo:{ENV}:Meta),其中内容形如:

<?xml version="1.0"?>
<configuration>
    <appSettings>
        <!-- Should change the apollo config service url for each environment -->
        <add key="Apollo:DEV:Meta" value="http://localhost:8080"/>
        <add key="Apollo:FAT:Meta" value="http://localhost:8080"/>
        <add key="Apollo:UAT:Meta" value="http://localhost:8080"/>
        <add key="Apollo:PRO:Meta" value="http://localhost:8080"/>
    </appSettings>
</configuration>

或者直接Apollo:MetaServer(优先级高于上面,该方式不需要配置Apollo:Env)

<?xml version="1.0"?>
<configuration>
    <appSettings>
        <add key="Apollo:MetaServer" value="http://localhost:8080" />
    </appSettings>
</configuration>

1.2.4 本地缓存路径

Apollo客户端会把从服务端获取到的配置在本地文件系统缓存一份,用于在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置,不影响应用正常运行。

本地缓存路径位于C:\opt\data\{appId}\config-cache,所以请确保C:\opt\data\目录存在,且应用有读写权限。

1.2.5 可选设置

Cluster(集群)

Apollo支持配置按照集群划分,也就是说对于一个appId和一个环境,对不同的集群可以有不同的配置。

  • 我们可以在App.config或Web.Config文件中设置Apollo:Cluster来指定运行时集群(注意大小写)
  • 例如,下面的截图配置指定了运行时的集群为SomeCluster
  • apollo-net-apollo-cluster

Cluster Precedence(集群顺序)

  1. 如果Apollo:ClusterApollo:DataCenter同时指定:

    • 我们会首先尝试从Apollo:Cluster指定的集群加载配置
    • 如果没找到任何配置,会尝试从Apollo:DataCenter指定的集群加载配置
    • 如果还是没找到,会从默认的集群(default)加载
  2. 如果只指定了Apollo:Cluster

    • 我们会首先尝试从Apollo:Cluster指定的集群加载配置
    • 如果没找到,会从默认的集群(default)加载
  3. 如果只指定了Apollo:DataCenter

    • 我们会首先尝试从Apollo:DataCenter指定的集群加载配置
    • 如果没找到,会从默认的集群(default)加载
  4. 如果Apollo:ClusterApollo:DataCenter都没有指定:

    • 我们会从默认的集群(default)加载配置

1.3 使用非Properies格式的namespace

内部使用namespace的后缀来判断namespace类型,比如application.json时,会使用json格式来解析数据,内部默认实现了json和xml两种格式,可覆盖,yml和yaml可使用Apollo.ConfigAdapter.Yaml包,其他格式需要自行实现。

  1. 实现IConfigAdapter或者继承ContentConfigAdapter
  2. 使用ConfigAdapterRegister.AddAdapter注册实现的类的实例(Properties不能被覆盖)

1.4 .net core风格key支持

  1. Apollo.XXX => Apollo:XXX
  2. Apollo.{ENV}.Meta => Apollo:Meta:{ENV}

优先级低于原来的方式,具体可以参考Demo或者Tests

二、引入方式

安装包Com.Ctrip.Framework.Apollo.ConfigurationManager

三、客户端用法

3.1 获取默认namespace的配置(application)

IConfig config = await ApolloConfigurationManager.GetAppConfig(); //config instance is singleton for each namespace and is never null
string someKey = "someKeyFromDefaultNamespace";
string someDefaultValue = "someDefaultValueForTheKey";
string value = config.GetProperty(someKey, someDefaultValue);

通过上述的config.GetProperty可以获取到someKey对应的实时最新的配置值。

另外,配置值从内存中获取,所以不需要应用自己做缓存。

3.2 监听配置变化事件

监听配置变化事件只在应用真的关心配置变化,需要在配置变化时得到通知时使用,比如:数据库连接串变化后需要重建连接等。

如果只是希望每次都取到最新的配置的话,只需要按照上面的例子,调用config.GetProperty即可。

IConfig config = await ApolloConfigurationManager.GetAppConfig(); //config instance is singleton for each namespace and is never null
config.ConfigChanged += new ConfigChangeEvent(OnChanged);
private void OnChanged(object sender, ConfigChangeEventArgs changeEvent)
{
	Console.WriteLine("Changes for namespace {0}", changeEvent.Namespace);
	foreach (string key in changeEvent.ChangedKeys)
	{
		ConfigChange change = changeEvent.GetChange(key);
		Console.WriteLine("Change - key: {0}, oldValue: {1}, newValue: {2}, changeType: {3}", change.PropertyName, change.OldValue, change.NewValue, change.ChangeType);
	}
}

3.3 获取公共Namespace的配置

string somePublicNamespace = "CAT";
IConfig config = await ApolloConfigurationManager.GetConfig(somePublicNamespace); //config instance is singleton for each namespace and is never null
string someKey = "someKeyFromPublicNamespace";
string someDefaultValue = "someDefaultValueForTheKey";
string value = config.GetProperty(someKey, someDefaultValue);

3.4 获取多个Namespace的合并结果

string somePublicNamespace = "CAT";
IConfig config = await ApolloConfigurationManager.GetConfig(new [] { somePublicNamespaceConfigConsts.NamespaceApplication }); //config instance is singleton for each namespace and is never null
string someKey = "someKeyFromPublicNamespace";
string someDefaultValue = "someDefaultValueForTheKey";
string value = config.GetProperty(someKey, someDefaultValue);

3.4 Demo

apollo.net项目中有多个样例客户端的项目:

四、NETFramework 4.7.1+ ConfigurationBuilder支持

4.1 ApolloConfigurationBuilder

<configuration>
    <configBuilders>
        <builders>
            <add name="ApolloConfigBuilder1" type="Com.Ctrip.Framework.Apollo.AppSettingsSectionBuilder, Com.Ctrip.Framework.Apollo.ConfigurationManager" namespace="TEST1.test;application" keyPrefix="可选值" />
        </builders>
    </configBuilders>
</configuration>
  • namespace为可选值,该值对应apollo中的namespace。支持多个值,以,;分割,优先级从低到高
  • keyPrefix为可选值,当值不是IsNullOrWhiteSpace时生效

4.2 ConnectionStringsSectionBuilder

<configuration>
    <configBuilders>
        <builders>
            <add name="ConnectionStringsSectionBuilder1" type="Com.Ctrip.Framework.Apollo.ConnectionStringsSectionBuilder, Com.Ctrip.Framework.Apollo.ConfigurationManager" namespace="TEST1.test" keyPrefix="可选值" defaultProviderName="MySql.Data.MySqlClient" />
        </builders>
    </configBuilders>
</configuration>
  • namespace为可选值,该值对应apollo中的namespace。支持多个值,以,;分割,优先级从低到高
  • defaultProviderName为可选值,默认值为System.Data.SqlClient,,对应ConnectionString的ProviderName。
  • keyPrefix为可选值,没有配置时值为节点名(一般是connectionStrings),值是WhiteSpace时则不生效
  • 通过ConnectionStrings:ConnectionName:ConnectionString或者ConnectionStrings:ConnectionName来设置连接字符串(同时指定时ConnectionStrings:ConnectionName:ConnectionString优先级高)
  • 通过ConnectionStrings:ConnectionName:ProviderName来指定使用其他数据库,比如MySql.Data.MySqlClient来指定是MySql

4.3 CommonSectionBuilder

通过反射结点类型,动态递归添加到节点类型中,此方法灵活,适应绝大部分节点。通过读取属性的[ConfigurationProperty]值和配置中的值关联

<configuration>
    <configBuilders>
        <builders>
            <add name="CommonSectionBuilder" type="Com.Ctrip.Framework.Apollo.CommonSectionBuilder, Com.Ctrip.Framework.Apollo.ConfigurationManager" namespace="TEST1.test" keyPrefix="可选值" />
        </builders>
    </configBuilders>
</configuration>
  • namespace为可选值,该值对应apollo中的namespace。支持多个值,以,;分割,优先级从低到高
  • keyPrefix为可选值,没有配置时值为节点名,值是WhiteSpace时则不生效

4.4 NodeReplaceSectionBuilder

直接使用apollo中配置的xml替换掉原来的节点xml

<configuration>
    <configBuilders>
        <builders>
            <add name="NodeReplaceSectionBuilder" type="Com.Ctrip.Framework.Apollo.NodeReplaceSectionBuilder, Com.Ctrip.Framework.Apollo.ConfigurationManager" namespace="TEST1.test" key="可选值" />
        </builders>
    </configBuilders>
</configuration>
  • namespace为可选值,该值对应apollo中的namespace。支持多个值,以,;分割,优先级从低到高
  • key为可选值,当为IsNullOrWhiteSpace时值为节点名

五、FAQ

5.1 Apollo内部HttpClient如何配置代理

在读取任何配置之前执行如下代码

ConfigUtil.UseHttpMessageHandler(new HttpClientHandler
{
    UseProxy = true,
    Proxy = new WebProxy(new Uri("http://代理地址"))
});

5.2 如何跳过meta service的服务发现

在配置文件中添加Apollo:ConfigServer

<appSettings>
+   <add key="Apollo:ConfigServer" value="多个值可以使用,或者;连接" />
</appSettings>

5.3 如何使用访问密钥

配置对应的环境的Secret即可

<appSettings>
+   <add key="Apollo:Secret" value="服务端配置的值" />
</appSettings>

5.4 如何优先使用环境变量

配置Apollo.EnvironmentVariablePriority或者Apollo:EnvironmentVariablePriority值为1或者true(优先从环境变量中读取)后,则Apollo配置则优先从环境变量中读取(和现在读取顺序相反)

5.5 如何不更改framework版本的情况下使用ConfigurationBuilder

  1. 运行时必须是.NET Framework 4.7.1+
  2. 在项目文件的PropertyGroup节点里添加true

在4.0版本中使用此功能时不建议使用ApolloConfigurationManager(可能存在运行时错误)。

5.6 如何允许类似Sping的PlaceHolder功能

<add key="Apollo:EnablePlaceholder" value="true" />