如果想将传统的config配置(如web.config)转成json配置,可以使用config2json工具
- NETFramework 4.0+(4.7.1+支持ConfigurationBuilder)
- NETStandard 2.0
Apollo客户端依赖于AppId
,Environment
等环境信息来工作,所以请确保阅读下面的说明并且做正确的配置:
1.2.0 指定到网络主机的最大连接数
由于Long Poll会占用连接数量,因此可能需要配置最大连接数
仅.NET Framework需要配置
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。
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
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>
Apollo客户端会把从服务端获取到的配置在本地文件系统缓存一份,用于在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置,不影响应用正常运行。
本地缓存路径位于C:\opt\data\{appId}\config-cache
,所以请确保C:\opt\data\
目录存在,且应用有读写权限。
Cluster(集群)
Apollo支持配置按照集群划分,也就是说对于一个appId和一个环境,对不同的集群可以有不同的配置。
Cluster Precedence(集群顺序)
-
如果
Apollo:Cluster
和Apollo:DataCenter
同时指定:- 我们会首先尝试从
Apollo:Cluster
指定的集群加载配置 - 如果没找到任何配置,会尝试从
Apollo:DataCenter
指定的集群加载配置 - 如果还是没找到,会从默认的集群(
default
)加载
- 我们会首先尝试从
-
如果只指定了
Apollo:Cluster
:- 我们会首先尝试从
Apollo:Cluster
指定的集群加载配置 - 如果没找到,会从默认的集群(
default
)加载
- 我们会首先尝试从
-
如果只指定了
Apollo:DataCenter
:- 我们会首先尝试从
Apollo:DataCenter
指定的集群加载配置 - 如果没找到,会从默认的集群(
default
)加载
- 我们会首先尝试从
-
如果
Apollo:Cluster
和Apollo:DataCenter
都没有指定:- 我们会从默认的集群(
default
)加载配置
- 我们会从默认的集群(
内部使用namespace的后缀来判断namespace类型,比如application.json时,会使用json格式来解析数据,内部默认实现了json和xml两种格式,可覆盖,yml和yaml可使用Apollo.ConfigAdapter.Yaml包,其他格式需要自行实现。
- 实现IConfigAdapter或者继承ContentConfigAdapter
- 使用
ConfigAdapterRegister.AddAdapter
注册实现的类的实例(Properties不能被覆盖)
- Apollo.XXX => Apollo:XXX
- Apollo.{ENV}.Meta => Apollo:Meta:{ENV}
安装包Com.Ctrip.Framework.Apollo.ConfigurationManager
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对应的实时最新的配置值。
另外,配置值从内存中获取,所以不需要应用自己做缓存。
监听配置变化事件只在应用真的关心配置变化,需要在配置变化时得到通知时使用,比如:数据库连接串变化后需要重建连接等。
如果只是希望每次都取到最新的配置的话,只需要按照上面的例子,调用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);
}
}
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);
string somePublicNamespace = "CAT";
IConfig config = await ApolloConfigurationManager.GetConfig(new [] { somePublicNamespace, ConfigConsts.NamespaceApplication }); //config instance is singleton for each namespace and is never null
string someKey = "someKeyFromPublicNamespace";
string someDefaultValue = "someDefaultValueForTheKey";
string value = config.GetProperty(someKey, someDefaultValue);
apollo.net项目中有多个样例客户端的项目:
- Apollo.AspNet.Demo(通过Web.config配置)
- Apollo.ConfigurationManager.Demo(通过环境变量配置)
<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时生效
<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
通过反射结点类型,动态递归添加到节点类型中,此方法灵活,适应绝大部分节点。通过读取属性的[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时则不生效
直接使用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时值为节点名
在读取任何配置之前执行如下代码
ConfigUtil.UseHttpMessageHandler(new HttpClientHandler
{
UseProxy = true,
Proxy = new WebProxy(new Uri("http://代理地址"))
});
在配置文件中添加Apollo:ConfigServer
<appSettings>
+ <add key="Apollo:ConfigServer" value="多个值可以使用,或者;连接" />
</appSettings>
配置对应的环境的Secret即可
<appSettings>
+ <add key="Apollo:Secret" value="服务端配置的值" />
</appSettings>
配置Apollo.EnvironmentVariablePriority或者Apollo:EnvironmentVariablePriority值为1或者true(优先从环境变量中读取)后,则Apollo配置则优先从环境变量中读取(和现在读取顺序相反)
- 运行时必须是.NET Framework 4.7.1+
- 在项目文件的PropertyGroup节点里添加true
在4.0版本中使用此功能时不建议使用ApolloConfigurationManager(可能存在运行时错误)。
5.6 如何允许类似Sping的PlaceHolder功能
<add key="Apollo:EnablePlaceholder" value="true" />