面臨的問題
在大型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