Apache ServiceComb Kie----一個語義型配置中心

此次我想分享如何管理分佈式應用系統中的配置項,咱們的實踐與遇到的問題java


爲何要用配置中心

我相信你們在開發的過程當中,常常會遇到的問題是git

  • 我有個新的特性,可是我須要對其進行控制,在必要時能將功能關閉或打開
  • 連接數據庫的線程池須要調整
  • 訪問某個目標的超時時間須要調整
  • 調節任務執行器的線程池大小
  • 隨着業務發展,幾百,幾千的虛機或是容器實例配置須要管理

難道每次配置我都要去代碼庫中改變而後從新發布版本麼?我在曾經的項目中就是這麼作的,得益於當時完善的CICD,咱們只須要幾分鐘就能夠完成這樣的一次變動,可是依然要面臨進程的重啓,因此以後的實踐中咱們直接將配置管理放入到了編程框架中,並配以中心式的配置管理服務github

使用編程框架

我在這篇分享中有大量分享歡迎參考,Go語言分佈式系統配置管理實踐--go archaius
數據庫

有了此次改變後咱們就作到了在運行時讓配置生效,不用經過流水線從新發布新版本。apache

在流水線中能作的只是在發佈一個服務時,對接配置中心的API,對相關配置進行變動。。好比進行一次新版本的發佈,更改金絲雀發佈策略。編程

配置逐漸變得難以管理

配置中心的數據模型逐漸沒法知足需求json

Dimension概念

配置項以Dimension劃分 Dimension由{service}@{app}#{version}表示,也就是服務相關信息拼接而成的字符串。bash

Dimension就是一個惟一的ID,關聯各個配置項,也就是一段json結構體app

{
"timout":"1s",
"pool_size":"10",
}複製代碼

也就是說咱們對着微服務,版本,所屬應用3個維度來下發信息
負載均衡

若是要更改微服務級別的服務,即不區分版本,咱們就對{service}@{app}這個dimension進行變動。

能力就僅限於這兩個層級了。

隨着業務的發展咱們發現這樣的結構體不能知足一些場景

  • 配置中心圍繞微服務的治理概念進行設計(超時,熔斷,負載均衡策略等配置),可是用戶的業務系統配置也使用這套配置中心和開發框架管理(好比我說的某個功能開關),不應讓用戶去理解微服務,版本,app的概念,而是直白的,讓用戶更改配置,好比按照環境去下發environment=test或者production
  • 服務的元數據不僅是version,app,可能還有instance,也就是對着服務進程,只改變某個進程的配置進行小範圍測試,除了instance還有更多元數據須要考慮,咱們沒法作到精準控制,好比按照project

key變得複雜

因爲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",
}複製代碼

難道咱們都要繼續拼接下去?咱們來看看問題

  • key語義學習成本高,語義容易混亂
  • 全部的key集中在一個列表中管理,管理成本高。
  • 當拼接規則複雜起來,人類不可讀。
  • Key設計幾乎沒法擴展或者變動(須要極高成本才能變動)
固然咱們能夠給json的value傳入個json,yaml,java properties值,key用更大的維度來表示,好比文件名,可是一個圍繞微服務概念設計的配置中心作不到通用,Dimension須要更加靈活,讓人易於理解。


Apache ServiceComb Kie

在發展的過程當中,咱們從新設計了配置中心,不僅圍繞微服務場景,或者像kubernetes的config map圍繞容器,而是但願可以成爲一個通用的配置中心,讓更多的生態接入。

項目地址:github.com/apache/serv…

從新設計的結構體。

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的新特性進行分享,經過這篇我但願經過分享讓你們對複雜分佈式系統中的配置管理實踐有些瞭解。

相關文章
相關標籤/搜索