1. 程式人生 > >個推基於Consul的配置管理

個推基於Consul的配置管理

方案 一般來說 動態 互相調用 img https 示例 相關配置 lua實現

作者:個推應用平臺基礎架構高級研發工程師 阿飛
在微服務架構體系中,由於微服務眾多,服務之間又有互相調用關系,因此,一個通用的分布式配置管理是必不可少的。一般來說,配置管理需要解決配置集中管理、在系統運行期間可實現動態配置、配置修改後支持自動刷新等問題。
在大多數微服務體系中,都會有一個名為配置文件的功能模塊來提供統一的分布式配置管理。構建配置中心,統一對應用中各個微服務進行管理,對微服務體系的意義重大。

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的格式如下:

/ProductLine_Prefix/Usage_Prefix/Environmental_Correlation_Prefix/Config_Item_Path

其中,
ProductLine_Prefix:用來隔離不同產品線的配置;
Usage_Prefix:用來區分配置的用途;
Environmental_Correlation_Prefix:用來分隔與環境相關的配置;

Config_Item_Path:具體的配置項。

配置在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:

{{ 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會負責將其拉取下來,然後調用相關的代碼進行配置的更新。
技術分享圖片

基於Consul的二次開發-CCenter

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

總結

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

個推基於Consul的配置管理