1. 程式人生 > >微服務架構為什麼需要配置中心?

微服務架構為什麼需要配置中心?

在系統架構中,和安全、日誌、監控等非功能需求一樣,配置管理也是一種非功能需求。配置中心是整個微服務基礎架構體系中的一個元件,如下圖,它的功能看上去並不起眼,無非就是簡單配置的管理和存取,但它是整個微服務架構中不可或缺的一環。另外,配置中心如果真得用好了,它還能推動技術組織持續交付和 DevOps 文化轉型。

本文介紹在分散式微服務環境下,應用配置管理背後的業務需求,配置的各種分類和一些高階應用場景。(本文結合我在極客時間《微服務架構實踐 160 講》視訊課程內容整理而成,戳此可試看課程

配置定義和形態

配置其實是獨立於程式的可配變數,同一份程式在不同配置下會有不同的行為,常見的配置有連線字串,應用配置和業務配置等。

配置有多種形態,下面是一些常見的:

  • 程式內部 hardcode,這種做法是反模式,一般我們 不建議!

  • 配置檔案,比如 Spring 應用程式的配置一般放在 application.properties 檔案中。

  • 環境變數,配置可以預置在作業系統的環境變數裡頭,程式執行時讀取,這是很多 PaaS 平臺,比如 Heroku 推薦的做法,參考 12 factor app[附錄 1]。

  • 啟動引數,可以在程式啟動時一次性提供引數,例如 java 程式啟動時可以通過 java -D 方式配啟動引數。

  • 基於資料庫,有經驗的開發人員會把易變配置放在資料庫中,這樣可以在執行期靈活調整配置,這個做法和配置中心的思路已經有點接近了。

傳統應用配置的痛點

在沒有引入配置中心之前,一般企業研發都會面臨幾個問題:

1. 配置散亂格式不標準

有的用 properties 格式,有的用 xml 格式,還有的存 DB,團隊傾向自造輪子,做法五花八門。

2. 主要採用本地靜態配置,配置修改麻煩

配置修改一般需要經過一個較長的測試釋出週期。在分散式微服務環境下,當服務例項很多時,修改配置費時費力。

3. 易引發生產事故

這個是我親身經歷,之前在一家網際網路公司,有團隊在釋出的時候將測試環境的配置帶到生產上,引發百萬級資損事故。

4. 配置缺乏安全審計和版本控制功能

誰改的配置?改了什麼?什麼時候改的?無從追溯,出了問題也無法及時回滾。

現代應用配置核心需求

近年,持續交付和 DevOps 理念開始逐步被一線企業接受,微服務架構和容器雲也逐漸在一線企業落地,這些都對應用配置管理提出了更高的要求:

1. 交付件和配置分離

傳統做法應用在打包部署時,會為不同環境打出不同配置的包,例如為開發 / 測試 /UAT/ 生產環境分別製作釋出包,每個包裡頭包含環境特定配置。

現代微服務提倡雲原生 (Cloud Native) 和不可變基礎設施(Immutable Infrastructure)的理念,推薦採用如容器映象這種方式打包和交付微服務,應用映象一般只打一份,可以部署到不同環境。這就要求交付件(比如容器映象)和配置進行分離,交付件只製作一份,並且是不可變的,可以部署到任意環境,而配置由配置中心集中管理,所有環境的配置都可以在配置中心集中配,執行期應用根據自身環境到配置中心動態拉取相應的配置。

2. 抽象標準化

企業應該由框架或者中介軟體團隊提供標準化的配置中心服務 (Configuration as a Service),封裝遮蔽配置管理的細節和配置的不同格式,方便使用者進行自助式的配置管理。一般使用者只需要關注兩個抽象和標準化的介面:

  1. 配置管理介面 UI,方便應用開發人員管理和釋出配置。

  2. 封裝好的客戶端 API,方便應用整合和獲取配置。

3. 多環境多叢集

現代微服務應用大都採用多環境部署,一般標準化的環境有開發 / 測試 /UAT/ 生產等,有些應用還需要多叢集部署,例如支援跨機房或者多版本部署。配置中心需要支援對多環境和多叢集應用配置的集中式管理。

4. 高可用

配置中心必須保證高可用,不能隨便掛,否則可能大面積影響微服務。在極端的情況下,如果配置中心不可用,客戶端也需要有降級策略,保證應用可以不受影響。

5. 實時性

配置更新需要儘快通知到客戶端,這個週期不能太長,理想應該是實時的。有些配置的實時性要求很高,比方說主備切換配置或者藍綠部署配置,需要秒級切換配置的能力。

6. 治理

配置需要治理,具體包括:

  • 配置審計,誰、在什麼時間、修改了什麼配置,需要詳細的審計,方便出現問題時能夠追溯。

  • 配置版本控制,每次變更需要版本化,出現問題時候能夠及時回滾到上一版本。

  • 配置許可權控制,配置變更釋出需要認證授權,不是所有人都能修改和釋出配置。

  • 灰度釋出,高階的配置治理支援灰度釋出,配置釋出時可以先讓少數例項生效,確保沒有問題再逐步放量。

配置分類

配置目前還沒有特別標準的分類方法,我簡單把配置分為靜態和動態兩大類,每一類再分為若干子類,如下圖:

1. 靜態配置

所謂靜態配置,就是在程式啟動前一次性配好,啟動時一次性生效,在程式執行期一般不會變化的配置。具體包括:

  • 1.1 環境相關配置

有些配置是和環境相關的,每個環境的配置不一樣,例如資料庫、中介軟體和其它服務的連線字串配置。這些配置一次性配好,執行期一般不變。

  • 1.2 安全配置

有些配置和安全相關,例如使用者名稱,密碼,訪問令牌,許可證書等,這些配置也是一次性配好,執行期一般不變。因為涉及安全,相關資訊一般需要加密儲存,對配置訪問需要許可權控制。

2. 動態配置

所謂動態配置,就是在程式的執行期可以根據需要動態調整的配置。動態配置讓應用行為和功能的調整變得更加靈活,是持續交付和 DevOps 的最佳實踐。具體包括:

  • 2.1 應用配置

和應用相關的配置,例如服務請求超時,執行緒池和佇列的大小,快取過期時間,資料庫連線池的容量,日誌輸出級別,限流熔斷閥值,服務安全黑白名單等。一般開發或者運維會根據應用的實際執行情況調整這些配置。

  • 2.2 業務配置

和業務相關的一些配置,例如促銷規則,貸款額度,利率等業務引數,A/B 測試引數等。一般產品運營或開發人員會根據實際的業務需求,動態調整這些引數。

  • 2.3 功能開關

在英文中也稱 Feature Flag/Toggle/Switch,簡單的只有真假兩個值,複雜的可以是多值引數。功能開關是 DevOps 的一種最佳實踐,在運維中有很多應用場景,比如藍綠部署,灰度開關,降級開關,主備切換開關,資料庫遷移開關等。功能開關在國外網際網路公司用得比較多,國內還沒有普及開,所以我在下一節會給出一些功能開關的高階應用場景。

配置中心高階應用場景

場景一、藍綠部署

藍綠部署的傳統做法是通過負載均衡器切流量來實現,如下圖左邊所示。這種做法一般研發人員無法自助操作,需要提交工單由運維介入操作,操作和反饋週期比較長,出了問題回退還需運維人員介入,所以回退也比較慢,總體風險比較高。

藍綠部署也可以通過配置中心 + 功能開關的方式來實現,如上圖右邊所示。開發人員在上線新功能時先將新功能隱藏在動態開關後面,開關的值在配置中心裡頭配。剛上線時新功能暫不啟用,走老功能邏輯,然後開發人員通過配置中心開啟開關,這個時候新功能就啟用了。一旦發現新功能有問題,可以隨時把開關關掉切回老功能。這種做法開發人員可以全程自助實現藍綠部署,不需要運維人員介入,反饋週期短效率高。

場景二、限流降級

當業務團隊在搞促銷,或者是系統受 DDOS 攻擊的時候,如果沒有好的限流降級機制,則系統很容易被洪峰流量沖垮,這個時候所有使用者無法訪問,體驗糟糕,如下圖左邊所示。

所以我們需要限流降級機制來應對流量洪峰。常見做法,我們一般會在應用的過濾器層或者是閘道器代理層新增限流降級邏輯,並且和配置中心配合,實現限流降級開關和引數的動態調整。如果促銷出現流量洪峰,我們可以通過配置中心啟動限流降級策略,比如對於普通使用者,我們可以先給出“網路不給力,請稍後再試”的友好提示,對於高階 VIP 使用者,我們仍然保證他們的正常訪問。

國內電商巨頭阿里,它內部的系統大量採用限流降級機制,實現方式基於其內部的 diamond+sentinel 配置管理系統。如果沒有限流降級機制的保護,則阿里的系統也無法抵禦雙十一帶來的洪峰流量衝擊。

場景三、資料庫遷移

LaunchDarkly 是一家提供配置既服務 (Configuration as a Service) 的 SAAS 服務公司,它在其部落格上給出了一片關於使用功能開關實現資料庫遷移的案例文章,該案例基於其內部一次成功的資料庫遷移實踐,從 MongoDB 遷移到 DynamoDB[參考附錄 2],下圖是展示了一個簡化的遷移流程:

簡化遷移騰挪流程如下:

  1. 開發人員先在應用端的 DAO 層埋好資料雙寫雙讀、以及資料比對邏輯。雙寫雙讀邏輯由開關控制,開關的值可在配置中心配。

  2. 先保證應用 100% 讀寫 mongoDB,然後先放開 10% 的 DynamoDB 雙寫,也稱金絲雀寫 (Canary Write),確保金絲雀寫沒有功能和效能問題。

  3. 逐步放量 DyanamoDB 寫到 100%,確保全量雙寫沒有功能和效能問題。

  4. 放開 10% 的 DynamoDB 雙讀,也稱金絲雀讀 (Canary Read),通過比對邏輯確保金絲雀讀沒有邏輯和效能問題。

  5. 逐步放量 DynamoDB 讀到 100%,通過比對邏輯確保全量雙讀沒有邏輯和效能問題。

  6. 關閉對 MongoDB 的讀寫,遷移完成。

整個遷移流程受配置中心的開關控制,可以靈活調整開關和引數,有問題可以隨時回滾,大大降低遷移風險。

場景四、A/B 測試

如果我們需要對電商平臺的結賬 (checkout) 功能進行改版,考慮到結賬功能業務影響面大,一下子上線風險大,為了減低風險,我們可以在配置中心配合下,對結賬功能進行 A/B 測試,簡化邏輯如下圖:

我們在配置中心中增加一個 ab_test_flag 開關,控制 A/B 測試邏輯:

  1. 如果 A/B 測試開關是關閉的 (ab_test_flag==false),那麼就走老的結賬邏輯。

  2. 如果 A/B 測試開關是開啟的 (ab_test_flag==true),並且是普通使用者 (user==regular,可以檢查資料庫中使用者型別),那麼就走老的結賬邏輯。

  3. 如果 A/B 測試開關是開啟的 (ab_test_flag==true),並且是 beta 使用者(user=beta),那麼就走改版後的新結賬邏輯。

通過配置中心,我們可以靈活調整開關,先對新功能進行充分的 beta 試驗,再考慮全量上線,大大降低關鍵業務新功能的上線風險。

公司案例和產品

在一線前沿的網際網路公司,配置中心都是其技術體系中的關鍵基礎服務,下圖給出一些公司案例產品:

  1. 阿里巴巴中介軟體部門很早就自研了配置中心 Diamond,並且是開源的。Diamond 對阿里系統的靈活穩定性發揮了至關重要的作用。開源版本的 Diamond 由於研發時間比較早,使用的技術比較老,功能也不夠完善,目前社群不熱已經不維護了。

  2. Facebook 內部也有一整套完善的配置管理體系 [可參考其論文,附錄 3],其中一個產品叫 Gatekeeper,目前沒有開源。

  3. Netflix 內部有大量的微服務,它的服務的穩定靈活性也重度依賴於配置中心。Netflix 開源了它的配置中心的客戶端,叫變色龍 Archaius[參考附錄 4],比較可惜的是,Netflix 沒有開源它的配置中心的伺服器端。

  4. Apollo[參考附錄 5] 是攜程框架部研發並開源的一款配置中心產品,企業級治理功能完善,目前社群比較火,在 github 上有超過 5k 星,在國內眾多網際網路公司有落地案例。如果企業打算引入開源的配置中心,那麼 Apollo 是我推薦的首選

  5. 百度之前也開源過一個叫 Disconf[參考附錄 6] 的配置中心產品,作者是前百度資深工程師廖綺綺。在 Apollo 沒有出來之前,Disconf 在社群是比較火的,但是自從廖琦琦離開百度之後,他好像沒有足夠精力投入維護這個專案,目前社群活躍度已經大不如前。

結論
  1. 配置中心是微服務基礎架構中不可或缺的核心元件,現代微服務架構和雲原生環境,對應用配置管理提出了更高的要求。

  2. 配置中心有眾多的應用場景,配置中心 + 功能開關是 DevOps 最佳實踐。用好配置中心,它能幫助技術組織實現持續交付和 DevOps 文化轉型。

  3. 攜程開源的 Apollo 配置中心,企業級功能完善,經過大規模生產驗證,社群活躍度高,是開源配置中心產品的首選。

附錄如下:

  1. https://12factor.net/config

  2. https://blog.launchdarkly.com/feature-flagging-to-mitigate-risk-in-database-migration/

  3. http://sigops.org/sosp/sosp15/current/2015-Monterey/printable/008-tang.pdf

  4. https://github.com/Netflix/archaius

  5. https://github.com/ctripcorp/apollo

  6. https://github.com/knightliao/disconf