源碼地址:https://github.com/qkbao/Disconf.Netgit
做者:青客寶 聯繫qq:後續奉上github
爲了更好的解決分佈式環境下多臺服務實例的配置統一管理問題,本文提出了一套完整的分佈式配置管理解決方案。結合.net項目具體狀況,實現了配置發佈的統一化,對配置進行持久化管理並對外提供restful接口,在此基礎上,基於ZooKeeper實現對配置更改的實時推送。系統參考了百度的Disconf,實現和改進了部分功能,是Disconf的.Net精簡版,功能有待進一步完善。web
l 簡單易用,用戶體驗良好redis
l 支持配置(KV配置項+配置文件)的分佈式化管理服務器
l 配置發佈、更新統一化:用戶統一在平臺上進行發佈、更新配置。restful
l 配置更新自動化:用戶在平臺更新配置,使用該配置的系統會自動發現該狀況,並應用新配置。架構
系統結構圖以下: app
初始化時,業務流程圖以下:分佈式
配置更新時,業務流程圖以下:測試
系統模塊架構圖以下:
配置管理模塊:統一管理用戶實例中本地配置文件和配置項
下載模塊:restful風格的下載配置文件和配置項
watch模塊:監控遠程配置文件和配置項的變化
配置管理模塊:支持配置模板(配置項或配置文件)的上傳、下載、更新
配置存儲模塊:管理全部配置的存儲和讀取,根據appName、version、environment來區分項目配置
通知模塊:當配置更新後,實時通知使用這些配置的全部實例
權限控制:web用戶的權限控制
在app.config或者web.config中的configSections節點下添加配置
<section name=」clientConfig」 type=」Disconf.Net.Client.ClientConfigSection,Disconf.Net.Client」/>
而後在appSettings同級別的節點上添加clientConfig配置,示例以下
<configSections> <section name=」clientConfig」 type=」Disconf.Net.Client.ClientConfigSection,Disconf.Net.Client」/> </configSections> <appSettings file=」appSettings.config」/> <clientConfig configSource=」clientConfig.config」/>
具體示例以下:
<clientConfig webApiHost=」http://192.168.1.100:8088/」 enableRemote=」true」> <clientInfo appName=」consoletest」 environment=」Dev」 version=」1.0.0.0」 clientName=」Console_1」/> <updateStrategy fileIgnores="notdown.txt" itemIgnores="aa,bb,cc " startedSync="true" retryTimes="3" retryIntervalSeconds="10" /> <preservation absolutePath="false" tmpRootDirectory="Tmp\Download\Configs" factRootDirectory="" tmpItemsLocalName="~items.xml" tmpFilesLocalName="~files.txt"/> </clientConfig>
節點名稱 |
必配 |
默認值 |
節點描述 |
|
webApiHost |
|
Y |
|
Rest服務器域名地址 |
enableRemote |
|
N |
true |
是否啓用遠程配置,默認true,設爲false的話表示不從遠程服務器下載配置 |
clientInfo |
appName |
Y |
|
客戶端程序名稱,注意大小寫要與服務端一致 |
environment |
Y |
|
當前客戶端程序所處環境,注意大小寫要與服務端一致 |
|
version |
Y |
|
當前客戶端程序版本,注意大小寫要與服務端一致 |
|
clientName |
N |
|
客戶端標識,用於服務端查看已更新客戶端,若是不設置則默認獲取客戶端電腦名稱 |
|
updateStrategy |
fileIgnores |
N |
|
要忽略更新的文件配置,以,分割,注意大小寫要與服務端一致 |
itemIgnores |
N |
|
要忽略更新的鍵值對配置,以,分割,注意大小寫要與服務端一致 |
|
startedSync |
N |
true |
啓動時是否同步加載,默認同步 |
|
retryTimes |
N |
3 |
當獲取失敗時的重試次數 |
|
retryIntervalSeconds |
N |
10 |
每次重試時間間隔,單位秒 |
|
preservation |
absolutePath |
N |
false |
是否絕對路徑,默認false。當false時,表示默認以 AppDomain.CurrentDomain.BaseDirectory爲比較點,注意:該配置同時適用於TmpRootDirectory、 FactRootDirectory,即要麼都只能絕對路徑,要麼都只能相對路徑 |
tmpRootDirectory |
N |
Tmp/Download/Configs |
下載下來的配置臨時保存文件夾根目錄 |
|
factRootDirectory |
N |
Configs |
配置文件實際所在的根目錄 |
|
tmpItemsLocalName |
N |
~items.xml |
在臨時目錄下用於保存全部鍵值對的文件名,設置爲空表示不保存,文件保存在TmpRootDirectory目錄下,因此注意不要與 實際配置文件名字衝突 |
|
|
tmpFilesLocalName |
N |
~files.txt |
在臨時目錄下用於保存全部文件配置名的文件名,設置爲空表示不保存,文件保存在TmpRootDirectory目錄下,因此注意不要與實際配置文件名字衝突 |
除了配置外,還須要設置更新策略,客戶端才能進行配置更新。目前,Rules設置僅支持編碼的方式進行,Rule分兩種:FileRule,ItemRule,下面分別進行描述:
FileRule:用於設置如何更新文件類型配置,其包含如下方法
方法名 |
描述 |
IFileRule MapTo(string refreshSectionName) |
註冊Rule規則,設置默認的文件配置映射 參數refreshSectionName表示更新回調時, ConfigurationManager.RefreshSection要刷新的節點名稱,默認採用遠程配置的configName |
IFileRule RefreshIgnores() |
不自動調用ConfigurationManager.RefreshSection方法更新配置 |
IFileRule CallBack(Action action) |
當文件下載完成而且替換本地對應文件後回調,注意此處將採用委託鏈的方式,即屢次調用均會被執行 |
ItemRule:用於設置如何更新鍵值對類型配置,其包含如下方法
方法名 |
描述 |
IItemRule MapTo(string propName) |
註冊Rule規則,設置默認的屬性映射參數 propName表示要賦值的屬性名,默認採用遠程的configName |
IItemRule SetProperty<T>(T entity, string propName = null, Func<string, object> typeConvert = null) |
更新指定實體的屬性值,按默認方式獲取實例屬性,注意此處屢次調用均會被執行 |
IItemRule SetProperty(object entity, PropertyInfo prop, Func<string, object> typeConvert = null) |
更新指定實體的屬性值,注意此處屢次調用均會被執行 |
IItemRule SetStaticProperty<T>(string propName = null, Func<string, object> typeConvert = null) |
更新靜態屬性的值,按默認方式獲取靜態屬性,注意此處屢次調用均會被執行 |
IItemRule SetStaticProperty(PropertyInfo prop, Func<string, object> typeConvert = null) |
更新靜態屬性的值,注意此處屢次調用均會被執行 |
IItemRule CallBack(Action<string> action) |
當值發生變動時如何進行回調,注意此處將採用委託鏈的方式,即屢次調用均會被執行 |
該類爲Client配置入口,經過Singleton提供惟一實例,除了提供Rules的配置入口外,還提供異常通知的事件
要使Disconf.Net.Client工做,必須顯示執行指定方法manager.Init(),而在init以前,還需設置Rule和Fault,能夠經過ConfigManager.Instance來獲取該類的實例對象,而後經過對應的Rule進行相關Rule設定,示例以下:
//要更新的文件 ConfigManager.Instance.FileRules.For("appSettings.config").CallBack(() => { Console.WriteLine("File changed notice twice"); }); //要更新的鍵值對 ConfigManager.Instance.ItemRules.For("Dai").MapTo("Person").SetStaticProperty<Program>().CallBack(v =>{ Console.WriteLine("Now item value:{0}", v); Console.WriteLine("Program.Person is {0} now", Program.Person); if (v.Length > 3) { throw new Exception("Too Long"); } }); //忽略更新到本地的鍵值對 ConfigManager.Instance.ItemRules.For("Peng").CallBack(v =>{ Console.WriteLine("Now item value:{0}", v); }); //異常處理 ConfigManager.Instance.Faulted+=Manager_Faulted; //Config初始化,包括ZooKeeper、scan等 ConfigManager.Instance.Init();
須要特別說明的是:
一、File由於屬於下載後覆蓋指定位置文件的方式,因此對於Rule能夠設置默認規則,如例子中的appSettings.config,其對應的就是config文件中的appSettings部分,此時若是不須要進行CallBack調用,且文件名稱(去除後綴)部分與Section一致,那麼這部分Rule設置能夠忽略,程序會在初始化時自動進行默認設置,而對於Item,由於沒法確認更新策略,因此若是不設置Rule,那麼就算從服務端獲取到了值,該部分也只能被忽略。
二、對於異常部分,程序只是簡單的經過Faulted事件來傳遞異常信息,該事件只有一個Exception類型的參數。
配置步驟:
一、 建立具體應用(項目)
二、 建立應用的配置模板(1~n個配置,如appSetting.config、redisconfig.config、rabbitMQConfig.config等配置模板)
三、 建立應用的環境(如:開發環境、測試環境、仿真環境等),修改相關的配置
四、 啓用對應的配置
五、 至此,client端就能夠獲取應用環境對應的全部配置
登錄進入配置管理界面
【新建】:填寫應用名稱,應用描述保存完成新建,返回可返回應用管理首頁。
【初始化ZooKeeper】:第一次啓動時Zookeeper初始化。
【編輯】:與新建界面一致,可修改應用名稱,應用描述,保存即返回應用管理首頁。
【編輯環境】:進入環境環境配置管理首頁。
【刪除】:刪除對應應用記錄。
顯示全部模板,操做環境配置前,須要先配置模板,根據模板對相應環境的配置進行操做。
【新建】:新增模板,填寫模板名稱、描述、類型、默認值版本號等,如選擇文件類型。可上傳文件讀取文件內容,版本號能夠選擇已經有的版本號,或者新建版本號。
【編輯】:操做同新建模板,可對模板內容進行修改。
【刪除】:點擊刪除可刪除對應模板記錄,如該模板在環境中存在配置項,則該模板不容許刪除,需刪除對應該模板的配置項,才能夠刪除對應模板。
【新增環境】點擊加號能夠新增環境,填寫環境名稱,描述保存便可。
【編輯環境】在對應環境上點擊鼠標右鍵便可彈出編輯菜單,點擊Edit便可編輯環境,能夠修更名稱內容等。
【配置首頁】:配置首頁根據版本進行分類,默認顯示頭部第一個版本,點擊其餘版本能夠進行切換,顯示的配置項是模板默認配置項,點擊啓用便可個性化賦值,針對不一樣環境進行不一樣的賦值。編輯可編輯相應配置,禁用等同於刪除配置。
【啓用配置】:名稱默認值不能修改,能夠點擊使用默認值,直接賦值,也能夠上傳文件使用文件內容,保存便可。
【編輯配置】:操做同啓用配置,保存便可修改值。
【禁用配置】:禁用等同於刪除配置,刪除對應模板配置項,可刪除對應模板。
【角色首頁】:
Ø 角色首頁展現角色列表,角色分爲超級管理員和非超級管理員;
Ø 超級管理員角色不展現;
Ø 超級管理員能夠看到全部非超級管理員角色,非超級管理員只能夠看到當前角色用戶建立的角色;
Ø 能夠新增角色,也能夠對角色進行編輯,只有在建立用戶時勾選是否爲系統管理員才能夠進行角色管理。
【新建角色】:
Ø 新建角色輸入角色名稱,能夠勾選的權限爲當前用戶所擁有的權限;
Ø 新建的角色做爲該用戶的下屬角色,可分配給當前用戶新建的用戶;
Ø 父級權限爲新建應用所增長的權限,之後每增長一個環境,就相應的增長該應用下的該環境權限,除超級管理員外的角色需對應勾選該權限才能看到該應用或者該權限,保存角色便可。
【編輯角色】:操做同新建角色,能夠對該角色進行名稱修改,權限修改。
管理用戶首頁,顯示全部用戶,可進行新建,編輯用戶等操做。
【新建用戶】:填寫姓名,用戶名,密碼,選擇角色(擁有對應角色權限、且能夠選擇的角色爲當前登錄用戶新建的角色),選擇是否爲系統管理員(系統管理員擁有新建用戶、新建角色權限),保存便可。
【編輯用戶】:操做同新建用戶,保存便可修改。