歡迎光臨
每天分享高質量文章

個推基於Consul的配置管理經驗

在微服務架構體系中,由於微服務眾多,服務之間又有互相呼叫關係,因此,一個通用的分佈式配置管理是必不可少的。一般來說,配置管理需要解決配置集中管理、在系統運行期間可實現動態配置、配置修改後支持自動掃清等問題。
在大多數微服務體系中,都會有一個名為配置檔案的功能模塊來提供統一的分佈式配置管理。構建配置中心,統一對應用中各個微服務進行管理,對微服務體系的意義重大。
Consul為什麼適合做配置管理

 

Consul作為輕量級的分佈式K/V儲存系統,搭建方便,可用性高,並且支持多資料中心,提供Web UI進行K/V管理。此外Consul還可以結合Consul-Template或者在代碼中引入Consul Client的相關依賴創建Watcher來實時Watch K/V的變化,是配置管理的不二之選。 
下圖為個推微服務體系基於Consul配置管理的整體設計。其中,CCenter就是在Consul的基礎上進行二次開發的配置中心。 
微服務體系下配置的分類和組織形式

 

在實踐中,不同產品線的配置會放置在Consul的不同路徑下,實現不同產品線配置之間的隔離。
按照配置的用途,可將同一產品線下的配置分為三類:
  1. API網關相關配置;

  2. 服務註冊與發現相關配置;

  3. 應用相關配置。

其中,每類配置會對應Consul上的不同目錄。
按照配置的變化特性,可將配置分為兩類:
  1. 環境相關的全域性配置,如MySQL等外部依賴相關的配置和其他與環境相關的配置,這類配置在開發測試生產環境中存在差異,需要為不同環境配置不同的值。

  2. 應用本身的配置,一般為不經常性發生變化、可動態調整、開關的配置。這類配置比較穩定,在初始化後,只有在需要時才會改動,通常會設置預設值。這兩類配置在Consul上會放在不同的子目錄下。這樣QA、運維只需要關註環境差異部分即可。

基於以上對配置的分類,最終Consul上的Key的格式如下:
  1. /ProductLine_Prefix/Usage_Prefix/Environmental_Correlation_Prefix/Config_Item_Path
其中:
  • ProductLine_Prefix:用來隔離不同產品線的配置;

  • Usage_Prefix:用來區分配置的用途;

  • EnvironmentalCorrelationPrefix:用來分隔與環境相關的配置;

  • ConfigItemPath:具體的配置項。

配置在Consul上的組織形式有以下兩種:
  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如何使用?
Consul-Template是一個後臺行程,它可以根據Watch Consul上K/V的變化,更新任意數量的模板,同時生成對應的檔案,之後還可以運行任意的命令。要使用Consul-Template一般需要定義兩個檔案:
1、模板檔案
模板檔案一般按照Go Template的格式進行編寫,示例如下:
config-tree.ctmpl:
  1. {{ tree /consul/path/to/configFiles | explode | toJSONPretty }}
該模板在/consul/path/to/configFiles路徑下的配置發生變化時,會渲染出一個Json格式的字串,其中包含了/consul/path/to/configFiles下所有的K/V。
config-kv.ctmpl:
  1. return {
  2. host='{{ printf "%s/mysql/host" (env "CONSUL_CONFIG_PREFIX") | key }}',
  3. port={{ keyOrDefault (printf "%s/mysql/port" (env "CON-SUL_CONFIG_PREFIX")) "3306" }},
  4. user='{{ printf "%s/mysql/user" (env "CONSUL_CONFIG_PREFIX") | key }}',
  5. password='{{ printf "%s/mysql/password" (env "CON-SUL_CONFIG_PREFIX") | key }}'
  6. }
該模板是按照配置項來渲染的,在該模板中使用了Consul-Template定義兩個方法key和keyOrDefault。其中,key會在Consul上對應的K/V創建後,再進行渲染模板;keyOrDefault則會在Consul上沒有對應的K/V時,使用預設值代替。
模板中還使用了 ” CONSULCONFIGPREFIX ” 這個環境變數,這樣,不同的產品線便可以使用同一個模板檔案,只需要修改” CONSULCONFIGPREFIX “這個環境變數的值即可。
2、配置檔案
配置檔案是按照HashiCorp Configuration Language(HCL)編寫的,示例如下:
  1. template {
  2. source = "config-tree.ctmpl",
  3. destination = "config-tree.json",
  4. command = "sh updateAndReload.sh config-tree.json”
  5. }
  6. template {
  7. source = "config-kv.ctmpl",
  8. destination = "config-kv.lua",
  9. command = "sh updateAndReload.sh config-kv.lua
  10. }
該配置檔案的作用是使用” source”指定的兩個模板檔案進行渲染,將渲染的結果分別儲存在” destination”指定的檔案中,儲存成功後,分別運行” command”指定的命令來更新並加載配置檔案。
配置的更新方式
在個推的微服務體系中,配置的更新方式有兩種:
1、替換配置檔案,reload服務 
2、呼叫服務接口直接更新記憶體中的配置
而在Java實現的微服務中,熱更新配置通常是在代碼中引入Consul Client的依賴,在應用啟動時,會初始化一個Watcher來監聽Consul上對應目錄下K/V的變化,相關的K/V發生變化時,Watcher會負責將其拉取下來,然後呼叫相關的代碼進行配置的更新。 
基於Consul的二次開發-CCenter

 

配置中心CCenter在Consul上提供了更友好的WEB UI,並且增加版本控制,每次配置的更新都會生成一個版本,在應用版本後,配置才真正生效,可以更加方便地進行配置版本間的差異比較,應用任意版本的配置。 
總結

 

以上就是個推在微服務實踐中,基於Consul實現的一套配置管理的方案,作為輕量級的分佈式K/V儲存系統, Consul非常適合用於配置管理,可以幫助開發者們方便、快速地搭建配置中心,結合Consul-Template則可以方便地實現配置的實時更新,在Consul的基礎上進行二次開發,實現了配置版本的有效控制,對微服務的配置管理起到了良好的輔助作用。

赞(0)

分享創造快樂