配置
配置(Configuration) 這個概念每個技術人都不陌生,可以說一個不提供幾個配置引數的系統都不好意思上線跟別的系統打招呼。
究其本質是我們人類無法掌控和預知一切,對映到軟體領域上,我們總是需要對系統的某些功能特性預留出一些控制的線頭,以便我們在未來需要的時候,可以人為的撥弄這些線頭從而控制系統的行為特徵,我把它叫做 “系統執行時(runtime)飛行姿態的動態調整“。
靜態配置
我們的系統存在一些外部依賴,這些依賴與業務無關,但是在開發階段具有不確定性,我們通常會將這些配置在屬性檔案中,如資料庫url,賬戶名,密碼,等,這些配置項基本不會輕易改變,而且配置也簡單,基本都是字串,所以稱他們為靜態配置
所謂靜態配置,就是在程式啟動前一次性配好,啟動時一次性生效,在程式執行期一般不會變化的配置。
具體包括:
- 環境相關配置
有些配置是和環境相關的,每個環境的配置不一樣,例如資料庫、中介軟體和其它服務的連線字串配置。這些配置一次性配好,執行期一般不變。
- 安全配置
有些配置和安全相關,例如使用者名稱,密碼,訪問令牌,許可證照等,這些也是一次性配好,執行期一般不變。因為涉及安全,相關資訊一般需要加密儲存,對配置訪問需要許可權控制。
動態配置
我們在業務開發中,會提前預料到業務的不確定性,而產生的複雜的業務配置項,型別簡單的可以使數字,字元,複雜點的可以是陣列,map,以及其混合的組織形式,由於業務需求,會需要常常發生改變,這類配置項,我們稱為動態配置。
所謂動態配置,就是在程式的執行期可以根據需要動態調整的配置。動態配置讓應用行為和功能的調整變得更加靈活,是持續交付和 DevOps 的最佳實踐。
- 2.1 應用配置
和應用相關的配置,例如服務請求超時,執行緒池和佇列的大小,快取過期時間,資料庫連線池的容量,日誌輸出級別,限流熔斷閥值,服務安全黑白名單等。一般開發或者運維會根據應用的實際執行情況調整這些配置。
- 2.2 業務配置
和業務相關的一些配置,例如促銷規則,貸款額度,利率等業務引數,A/B 測試引數等。一般產品運營或開發人員會根據實際的業務需求,動態調整這些引數。
- 2.3 功能開關
在英文中也稱 Feature Flag/Toggle/Switch,簡單的只有真假兩個值,複雜的可以是多值引數。功能開關是 DevOps 的一種最佳實踐,在運維中有很多應用場景,比如藍綠部署,灰度開關,降級開關,主備切換開關,資料庫遷移開關等。功能開關在國外網際網路公司用得比較多,國內還沒有普及開,所以我在下一節會給出一些功能開關的高階應用場景。
為什麼要有配置中心呢
在單機時代,我們都是用配置檔案來儲存配置項。一個配置檔案一般是一組配置項的集合或者叫配置集,一個系統根據邏輯模組劃分,可以有1到多個配置檔案。
在集中式開放時代,配置檔案基本夠用了,因為那是配置的管理通常不會成為一個很大的問題。如果要修改一個配置,登入到這臺機器上,登入到這臺生產機器上,vi配置這個配置檔案,然後reload一下並不是很大的負擔。
在分散式系統中,一次構建、釋出、上線是非常非常重的一個過程,它不像單機時代那樣重啟一臺機器、一個程式就可以了。
時效性
在分散式系統中,它涉及到將軟體包(例如war)分發到可能超過幾千臺機器,然後將幾千臺機器上的應用程式一一重啟這麼一個過程,超過2000臺機器的一個應用一次完整的釋出過程需要多長時間,相信大家都一定會清楚,所以從時效性上來說,配置中心是勢在必行。
統一管理
分發到幾千臺機器上,誰能保證幾千次配置都會一致,不會有哪個人手誤導致檔案更改有錯誤,所以有一個應用統一管理管理配置,之後其他應用需要更改本地配置的時候,來向配置中心拉取,之後替換配置,之後重新發布就好了,這樣就能保證所有機器上的配置的都一致。
分散式三項原則
在分散式計算技術的設計和實現中,CAP理論是一個重要的指導原則,其基本內容如下:
1、“C”是指一致性,即當一個Process(過程)修改了某個資料後,其他Process讀取這是資料是,得到的是更新後的資料,但並不是所有系統都 可以做到這一點。例如,在一些並非嚴格要求一致性的系統中,後來的Process得到的資料可能還是修改之前的資料,或者需要等待一定時間後才能得到修改 之後的資料,這被成為“弱一致性”,最經典的應用就是DNS系統。當使用者修改了DNS配置後,往往不會馬上在全網更新,必定會有一個延遲,這個延遲被稱為 “不一致視窗”,它的長度取決於系統的負載、冗餘的個數等因素。但對於某些系統而言,一旦寫入,後面讀取的一定是修改後的資料,如銀行賬戶資訊,這被稱為 “強一致性”。
2、“A”是指可用性。即系統總是能夠為使用者提供連續的服務能力。當使用者發出請求是,系統能給出響應(成功或者失敗),而且是立即給出響應,而不是等待其他事情完成才響應。如果需要等待某件事情完成才響應,那麼“可用性”就不存在了。
3、“P”是指容錯性。任何一個分散式計算系統都是由多個節點組成的。在正常情況下,節點與節點之間的通訊是正常的。但是在某些情況下,節點之間的通訊會 斷開,這種斷開成為“Partition”。在分散式計算的實現中,Partition是很常見的,因為節點不可能永遠不出故障,尤其是對於跨物理地區的 海量儲存系統而言,而容錯性則可以保證如果只是系統中的部分節點不可用,那麼相關的操作仍舊能夠正常完成。
演進中的配置中心
經過上面的內容,大家知道肯定要有一個配置中心來統一管理,通過配置中心繫統對每一條配置(每一個配置有唯一的配置ID)進行增刪改查。區分不同環境的配置,每個環境同一配置ID對應不同資料庫記錄。配置最終以key-value儲存在mysql資料庫中。
1.
可以有一個配置中心,通過配置中心對每一條配置進行增刪改查,配置最終以key-value儲存在mysql資料庫,配置對外服務,多機器部署,滿足效能需要。應用直接去呼叫配置中心提供的介面查詢配置,這樣可能對資料庫壓力太大,這樣的話可以在配置中心新增快取,每次查詢快取,這樣的話每次查詢的時候,就不會呼叫資料庫,每次可用直接查詢快取,每次更改配置的時候,順便更改快取,這樣能保證可用性和一致性。
很多時候,這樣可以基本上滿足我們對配置系統的基本需求,對配置的增刪改查,能容忍一段時間的資料不一致性。
這種設計,由於所有的配置都存放在集中式快取中,這樣集中式的快取也會有他的效能瓶頸。而且,每次配置的訪問都需要發起rpc請求(網路請求),因此考慮在客戶端引入本地快取(localCache,例如Ehcache)。
2.
能在服務端使用快取,為什麼不能再客戶端使用快取呢。
使用客戶端快取,那麼快取存在哪呢?
在客戶端使用快取可以分成三種,分散式快取,記憶體和硬碟。
但是這三種各有利弊。
分散式快取 那麼網路資源的耗費沒有得到節約,但是可以保證應用讀取的配置一致性的保證。
記憶體 不用耗費網路資源,很快,但是重啟會丟失配置
硬碟 不用耗費網路資源,不會丟失配置,相對來說會慢一些
考慮到,減少網路請求的因素,在客戶端引入localcache,雖然記憶體和硬碟可以節省網路資源,但是記憶體和硬碟都存在各自的缺點,那麼我們可以採用記憶體+硬碟的格式,把資源儲存再硬碟裡,每次重啟時在從硬碟中讀取之後載入到記憶體中。這樣的話來解決系統的高可用,高效能、可伸縮性。
一致性的話的我們可以採用縮短更新快取的問題來解決。也可以通過配置中心通知應用配置更新,應用從配置中心拉取最新的配置、更新本地配置並通知到應用。
php與配置中心
與c#、Java、Go、Python、Node.JS等等應用不同,php的程式不支援常駐記憶體,php每處理完一個請求後,資源都會被釋放掉;這也就意味著如果我們在請求進來時,都需要去訪問配置中心獲得各種配置資訊。
因為配置中心是外部程式,每次訪問都是跨程式通訊;假設獲取一個配置需要耗時1ms,那麼一百項配置就是0.1s;這是巨大的潛在效能影響。
get_key
函式時,便會自動去配置中心獲得新值,並重新快取。