此次我想分享如何管理分佈式應用系統中的配置項,咱們的實踐與遇到的問題java
我相信你們在開發的過程當中,常常會遇到的問題是git
難道每次配置我都要去代碼庫中改變而後從新發布版本麼?我在曾經的項目中就是這麼作的,得益於當時完善的CICD,咱們只須要幾分鐘就能夠完成這樣的一次變動,可是依然要面臨進程的重啓,因此以後的實踐中咱們直接將配置管理放入到了編程框架中,並配以中心式的配置管理服務github
我在這篇分享中有大量分享歡迎參考,Go語言分佈式系統配置管理實踐--go archaius
數據庫
有了此次改變後咱們就作到了在運行時讓配置生效,不用經過流水線從新發布新版本。apache
在流水線中能作的只是在發佈一個服務時,對接配置中心的API,對相關配置進行變動。。好比進行一次新版本的發佈,更改金絲雀發佈策略。編程
配置中心的數據模型逐漸沒法知足需求json
配置項以Dimension劃分 Dimension由{service}@{app}#{version}表示,也就是服務相關信息拼接而成的字符串。bash
Dimension就是一個惟一的ID,關聯各個配置項,也就是一段json結構體app
{
"timout":"1s",
"pool_size":"10",
}複製代碼
也就是說咱們對着微服務,版本,所屬應用3個維度來下發信息
負載均衡
若是要更改微服務級別的服務,即不區分版本,咱們就對{service}@{app}這個dimension進行變動。
能力就僅限於這兩個層級了。
隨着業務的發展咱們發現這樣的結構體不能知足一些場景
因爲json結構體的侷限性配置項的key愈來愈不易理解,key愈來愈長,好比
{
"ServiceB.timeout":"1s",
"ServiceB.user.getUser.timeout":"10",
}複製代碼
第一行表示訪問服務B時超時是多少
第二行表示到服務B的getUser API超時是多少
這還遠遠不夠,服務還有版本,環境,所屬app等多個字段,以下配置,因爲每一個字段沒有語義,咱們已經沒法知道第二個字段究竟是什麼意思了。
{
"ServiceB.v1.timeout":"1s",
"ServiceB.user.getUser.timeout":"10",
}複製代碼
難道咱們都要繼續拼接下去?咱們來看看問題
在發展的過程當中,咱們從新設計了配置中心,不僅圍繞微服務場景,或者像kubernetes的config map圍繞容器,而是但願可以成爲一個通用的配置中心,讓更多的生態接入。
從新設計的結構體。
kie取自key的諧音
正如名字所突出的,key成爲了同等公民,一個文件名"xxx,yaml",一個傳統的key「timeout」 均可以是一個key,咱們但願key簡單,易理解。而後圍繞key定義labels以表示複雜的語義
直接演示下運行效果:
key就在API path中(timeout),label與value在request body中定義
這句話的意思是,在對訂單服務進行訪問時,超時是1s
返回的respsonse body中,能夠看到版本號「revision」是2,這說明,label是第二次被使用(之間labels的歷史記錄已經被儲存了)
value具有type,不傳就是plain text,在前臺顯示是能夠根據類型作展現,更易讀
最重要的是labels,你能夠爲key定義多個labels,只有label徹底一致,才認爲這是個惟一的「Dimension」,我用label概念來代替了過去定死的Dimension。有了labels與key,你已經能夠自由的去定義本身的配置,表達本身的語義
我接着新建了一個配置,表示訪問該服務,要使用會話粘紙,可是能夠看到,revison是3,由於歷史管理是根據label記錄的,以讓用戶能夠根據labels來將全部key快速回滾到某個歷史狀態中,單一的回滾key來試圖恢復系統也許會引發更大的混亂。
咱們再來個稍微複雜的
此次咱們新建了一個複雜語義的label,表示:若是前臺訪問訂單服務的1.0.1,那麼負載均衡策略是round robin。
今天的介紹就簡單到這裏,後面會持續對kie的新特性進行分享,經過這篇我但願經過分享讓你們對複雜分佈式系統中的配置管理實踐有些瞭解。