多重环境下web.config配置管理解决方案

面临的问题

在大型web应用开发中,为了保证应用的质量,保证用户体验,我们开发时总要经历从开发,测试,beta到最终上线的过程。

因为不同的测试运行环境的参数都不同,所以在实际开发中我们可以编写多个web.config,每个web.config特定用于某个测试运行环境。这一切看上去似乎顺理成章,但随着你的应用越做越大,web.config也会越来越大,而麻烦也会随之而来。

复杂的web.config是很难进行维护的,而且牵一发动全身。比如你开发时有一个配置节要进行修改,那所有环境下的web.config对应的节也都要做相应的修改。特别是在web.config很大,各种测试环境又多的情况下,SCM管理员肯定会抓狂的……

化整为零

幸运的是,从.net 2.0开始,微软提供了configSource属性来让我们可以对web.config进行拆分。让我们来看个简单的例子:

[Web.config]

...

<system.web>

...

<profile configSource="profile.config" />

...

</system.web>

...

[profile.config]

<profile>

<properties>

<add name="Name" type="String" />

<add name="Age" type="Int32" />

</properties>

</profile>

在上面的例子中,我们对<system.web/profile>配置节进行了拆分,此配置节的具体配置是存储在另一个单独文件profile.config中,而web.config只需要通过configSource这个属性来指明配置节的具体配置存储在哪个文件中,web.config就会在运行时自动去寻找到那个文件并加载。

在进行拆分时,我们需要注意以下几点:

  • 只允许针对配置节(ConfigurationSection)进行拆分,而不能对配置节组(ConfigurationSectionGroup)或元素(Element)进行拆分。
  • 存储配置节内容的文件的后缀名需要小心,理论上文件名可以任意取,web.config都能读取。但出于安全的考虑,我们的后缀名最好是不能直接通过url访问的文件类型,以防止泄漏配置信息。所以.config是可以考虑的,.xml,.txt等后缀极力不推荐。
  • 默认情况下,如果特定配置节的config文件内容更改,iis是察觉不到的,所以不会重启程序池。假如你需要在特定配置节config文件修改后能让iis自动察觉到并进行重启,可以利用RestartOnExternalChanges属性,具体参见MSDN。

分而治之

技巧很简单,就是通过configSource属性来拆分web.config。那我们该如何来拆分我们的web.config以达到最有效的配置管理呢?因为我们的拆分是基于配置节层面的,所以问题又转化成哪些配置节我们需要拆分出来?

我们可以发现,有以下这些特征的配置节,可以列入我们的考虑范围:

  • 经常发生变化

某些配置节我们在开发时经常要修改或更新,如果能单独拉出来进行配置,这样修改时就不必碰web.config。

不同环境下的web.config都引用了同一个配置节config,所以这样的修改只需要做一次,而不必去修改所有环境的web.config。

  • 内容行数特别多

有时候web.config里有些配置节都是一大坨一大坨的,影响了web.config整体的审美观。我们完全可以把这些大坨的配置节内容单独抽取出来,这样一来,web.config就简洁多了,也便于阅读。

  • 不同环境下,配置节内容是不一样的

我们经常会有这样的配置节,在不同环境下的内容是不一样的(废话…不一样还要那么多不同的web.config干么… - -)。对于这种情况,我们完全可以考虑拆分出来,并且生成不同环境下的配置文件。而不同环境下的web.config只要引用对应环境的配置节文件即可。即使环境发生了变化,我们也不需要去动web.config,只要去修改相应环境下配置节文件即可。

当然,以上这三种特征不是互斥的,很可能某一配置节含有以上两种或三种特征。这些配置节更需要我们认真对待,通过多重策略来进行拆分。

各得其所

如果web.config很复杂,那拆分后的结果可能会多出一堆***.config文件,所以我们需要一套简单有效的命名规范来管理好这么多配置文件。

  • Web.config:在不同环境下的文件可以命名为Web.local.config, Web.beta.config, Web.release.config

  • 特征1,2配置节文件:可以取配置节的名字来命名文件,比如profile.config,规范一下应该是Web.profiling.config,类似还有Web.httpHanders.config,Web.httpModules.config等等。

  • 特征3配置节文件:假如有个dbConfig配置节(不同环境下的数据库连接配置),我们可以命名为Web.dbConfig.local.config,Web.dbConfig.beta.config,Web.dbConfig.release.config。

通过分而治之的管理和规范的命名,我们就可以轻松地进行配置管理,而不必整天面对那一大坨 看似一样 又有些不太一样 你必须清楚了解哪些不一样 可是又很难发现哪些不一样 最后连你自己都不知道是不是一样的web.config。

有些大型系统,可能每个web服务器上配置都还不一样,出于分布式考虑,可能每个web连接的数据库都不会不同。像这样的更复杂的情况,当然可以通过制定更复杂的命名规范来实现。但很多情况,线上的情况还是时刻发生变化的,比如某个db当了,需要web换到另一个db上访问。所以这个解决方案还不是很适合那些大型分布式web应用,可以考虑通过配置管理中间件来实现可行的解决方案。这个我会在今后研究并与大家进行分享。

 

原帖地址:http://it.dianping.com/using-configsource-to-split-web-confi.htm

posted @ 2008-10-24 13:20  Figo Yang  阅读(2790)  评论(5编辑  收藏  举报