[分佈式管理] 配置中心

配置中心的架構

我們可以看到,和一個軟件運行有關係的各種配置隸屬於不同的地方,所以,要讓它們落地還需要些不一樣的細節要處理。文本中,我們給了一個大概的架構圖。

[分佈式管理] 配置中心

在這個圖中可以看到,我們把配置錄入後,配置中心發出變更通知,配置變更控制器會來讀取最新的配置,然後應用配置。這看上去很簡單,但是有很多細節問題,下面我來一一說明。

為什麼需要一個變更通知的組件,而不是讓配置中心直接推送? 原因是,分佈式環境下,服務器太多,推送不太現實,而採用一個 Pub/Sub 的通知服務可以讓數據交換經濟一些。為什麼不直接 Pub 數據過去,還要訂閱方反向拉數據? 直接推數據當然可以,但讓程序反過來用 API 讀配置的好處是,一方面,API 可以校驗請求者的權限,另一方面,有時候還是需要調用配置中心的基本 API,比如下載最新的證書之類的。

還有就是,服務啟動時需要從服務中心拉一份配置下來。配置變更控制器部署在哪裡?是在每個服務器上呢,還是在一箇中心的地方? 我覺得因為這個事是要變更配置,變更配置又是有很多步驟的,所以這些步驟算是一個事務。

為了執行效率更好,事務成功率更大,建議把這個配置變更的控制放在每一臺主機上。平臺層的配置變更,有的參數是在服務啟動的命令行上,這個怎麼變更呢? 一般來說,命令行上的參數需要通過 Shell 環境變量做成配置項,然後通過更改系統環境變量,並重啟服務達到配置變更。操作系統的配置變更和平臺層的配置變更最好模塊化掉,就像雲服務中的不同尺寸的主機型號一樣。 這樣有利於維護和減少配置的複雜性。應用服務配置更新的標準化。 因為一個公司的應用由不同的團隊完成,所以,可能其配置會因為應用的屬性不同而不一樣。

為了便於管理,最好有統一的配置更新。一般來說,有的應用服務的配置是在配置文件中,有的應用服務的配置是通過調用 Admin API 的方式變更,不同的應用系統完全不一樣,你似乎完全沒有方法做成統一的。這裡給幾個方案。可以通過一個開發框架或 SDK 的方式來解決,也就是應用代碼找你這個 SDK 來要配置,並通過 observer 模式訂閱配置修改的事件,或是直接提供配置變更的 Admin 的 API。

這種方式的好處在於在開發期標準化,並可以規範開發;不好的是,耦合語言。通過一個標準應用運維腳本,讓應用方自己來提供應用變更時的腳本動作。這種方式雖然通過運維的方式標準化掉配置變更的接口,就可以通過一個配置控制器來統一操作各個應用變更,但是在這個腳本中各個應用方依然使用著各種不同的方式來變更配置。

這種方式的好處是不耦合語言,靈活,但對於標準化的建設可能不利,而且使用或者調用腳本是 Bug 很多的東西,容易出問題。或是結合上述兩種方案,不使用開發階段的 SDK 方式嵌入到應用服務中,而是為每個應用服務

配置中心的設計重點

配置中心主要的用處是統一和規範化管理所有的服務配置,也算是一種配置上的治理活動。所以,配置中心的設計重點應該放在如何統一和標準化軟件的配置項,其還會涉及到軟件版本、運行環境、平臺、中間件等一系列的配置參數。如果你覺得軟件配置非常複雜,那麼,你應該靜下心來仔細梳理或治理一下現有的配置參數,並簡化相應的配置,使用模塊會是一種比較好的簡化手段。

編程的本質是對 logic 和 control 的分離,所以,對於配置也一樣,其也有控制面上的配置和業務邏輯面上的配置,控制面上的配置最好能標準統一。

配置更新的時候是一個事務處理,需要考慮事務的問題,如果變更不能繼續,需要回滾到上個版本的配置。配置版本最好和軟件版本對應上。

配置更新控制器,需要應用服務的配合,比如,配置的 reload,服務的優雅重啟,服務的 Admin API,或是通過環境變量……這些最好是由一個統一的開發框架搞定。

配置更新控制器還擔任服務啟動的責任,由配置更新控制器來啟動服務。這樣,配置控制器會從配置中心拉取所有的配置,更新操作系統,設置好啟動時用的環境變量,並更新好服務需要的配置文件 ,然後啟動服務。(當然,你也可以在服務啟動的腳本中真正啟動服務前放上一段讓配置更新控制器更新配置的腳本。無論怎麼樣,這些都可以在運維層面實現,不需要業務開發人員知道。)


分享到:


相關文章: