做者:個推應用平臺基礎架構高級研發工程師 阿飛mysql
在微服務架構體系中,因爲微服務衆多,服務之間又有互相調用關係,所以,一個通用的分佈式配置管理是必不可少的。通常來講,配置管理須要解決配置集中管理、在系統運行期間可實現動態配置、配置修改後支持自動刷新等問題。 在大多數微服務體系中,都會有一個名爲配置文件的功能模塊來提供統一的分佈式配置管理。構建配置中心,統一對應用中各個微服務進行管理,對微服務體系的意義重大。nginx
Consul做爲輕量級的分佈式K/V存儲系統,搭建方便,可用性高,而且支持多數據中心,提供Web UI進行K/V管理。此外Consul還能夠結合Consul-Template或者在代碼中引入Consul Client的相關依賴建立Watcher來實時Watch K/V的變化,是配置管理的不二之選。 下圖爲個推微服務體系基於Consul配置管理的總體設計。其中,CCenter就是在Consul的基礎上進行二次開發的配置中心。
sql
在實踐中,不一樣產品線的配置會放置在Consul的不一樣路徑下,實現不一樣產品線配置之間的隔離。json
按照配置的用途,可將同一產品線下的配置分爲三類: 1.API網關相關配置; 2.服務註冊與發現相關配置; 3.應用相關配置。 其中,每類配置會對應Consul上的不一樣目錄。ruby
按照配置的變化特性,可將配置分爲兩類: 1.環境相關的全局配置 如MySQL等外部依賴相關的配置和其餘與環境相關的配置,這類配置在開發測試生產環境中存在差別,須要爲不一樣環境配置不一樣的值。 2.應用自己的配置 通常爲不常常性發生變化、可動態調整、開關的配置。這類配置比較穩定,在初始化後,只有在須要時纔會改動,一般會設置默認值。這兩類配置在Consul上會放在不一樣的子目錄下。這樣QA、運維只須要關注環境差別部分便可。架構
基於以上對配置的分類,最終Consul上的Key的格式以下:運維
/ProductLine_Prefix/Usage_Prefix/Environmental_Correlation_Prefix/Config_Item_Path
其中, ProductLine_Prefix:用來隔離不一樣產品線的配置; Usage_Prefix:用來區分配置的用途; Environmental_Correlation_Prefix:用來分隔與環境相關的配置; Config_Item_Path:具體的配置項。分佈式
1.以配置文件的形式組織,Consul上的一個K/V,對應一個配置文件,如nginx的配置文件。 2.以配置項的形式組織,將配置文件模板化,拆成一個個的配置項,每一個配置項對應Consul上的一個K/V,多個配置項對應一個配置文件。大部分配置文件自己都是以K/V的形式組織的,均適合模板化,模板化後便可以按照配置項的特性,在Consul上分紅不一樣的類別進行管理。微服務
Consul上的K/V,要如何生成可加載的應用,或可以使用的配置呢? 1.用Node和Lua實現的微服務的配置更新,使用Consul-Template來實現; 2.用Java實現的微服務的配置更新,經過Consul-Template工具(須要重啓應用)和在代碼中引入Consul Client的依賴建立Watcher(熱更新)這兩種方式來實現。工具
Consul-Template是一個後臺進程,它能夠根據Watch Consul上K/V的變化,更新任意數量的模板,同時生成對應的文件,以後還能夠運行任意的命令。要使用Consul-Template通常須要定義兩個文件: 1.模板文件 模板文件通常按照Go Template的格式進行編寫,示例以下: config-tree.ctmpl:
{{ tree /consul/path/to/configFiles | explode | toJSONPretty }}
該模板在/consul/path/to/configFiles路徑下的配置發生變化時,會渲染出一個Json格式的字符串,其中包含了/consul/path/to/configFiles下全部的K/V. config-kv.ctmpl:
return { host='{{ printf "%s/mysql/host" (env "CONSUL_CONFIG_PREFIX") | key }}', port={{ keyOrDefault (printf "%s/mysql/port" (env "CON-SUL_CONFIG_PREFIX")) "3306" }}, user='{{ printf "%s/mysql/user" (env "CONSUL_CONFIG_PREFIX") | key }}', password='{{ printf "%s/mysql/password" (env "CON-SUL_CONFIG_PREFIX") | key }}' }
該模板是按照配置項來渲染的,在該模板中使用了Consul-Template定義兩個方法key和keyOrDefault。其中,key會在Consul上對應的K/V建立後,再進行渲染模板;keyOrDefault則會在Consul上沒有對應的K/V時,使用默認值代替。
模板中還使用了 " CONSUL_CONFIG_PREFIX " 這個環境變量,這樣,不一樣的產品線即可以使用同一個模板文件,只須要修改" CONSUL_CONFIG_PREFIX "這個環境變量的值便可。
2.配置文件 配置文件是按照HashiCorp Configuration Language (HCL)編寫的,示例以下:
template { source = "config-tree.ctmpl", destination = "config-tree.json", command = "sh updateAndReload.sh config-tree.json」 } template { source = "config-kv.ctmpl", destination = "config-kv.lua", command = "sh updateAndReload.sh config-kv.lua」 }
該配置文件的做用是使用" source"指定的兩個模板文件進行渲染,將渲染的結果分別保存在" destination"指定的文件中,保存成功後,分別運行" command"指定的命令來更新並加載配置文件。
在個推的微服務體系中,配置的更新方式有兩種:
1.替換配置文件,reload服務
2.調用服務接口直接更新內存中的配置 而在Java實現的微服務中,熱更新配置一般是在代碼中引入Consul Client的依賴,在應用啓動時,會初始化一個Watcher來監聽Consul上對應目錄下K/V的變化,相關的K/V發生變化時,Watcher會負責將其拉取下來,而後調用相關的代碼進行配置的更新。
配置中心CCenter在Consul上提供了更友好的WEB UI,而且增長版本控制,每次配置的更新都會生成一個版本,在應用版本後,配置才真正生效,能夠更加方便地進行配置版本間的差別比較,應用任意版本的配置。
以上就是個推在微服務實踐中,基於Consul實現的一套配置管理的方案,做爲輕量級的分佈式K/V存儲系統, Consul很是適合用於配置管理,能夠幫助開發者們方便、快速地搭建配置中心,結合Consul-Template則能夠方便地實現配置的實時更新,在Consul的基礎上進行二次開發,實現了配置版本的有效控制,對微服務的配置管理起到了良好的輔助做用。