面試官:如果讓你寫個分散式配置中心,就問你慌不慌

猿天地發表於2020-11-27

前言

一位讀者朋友跟我反饋,能不能寫一篇比較全的配置中心的文章。自己最近在面試過程中有被面試官問:如何設計一個配置中心? 這個話題,由於自己在工作中也沒實際使用過配置中心,所以對於如何去設計是完全沒有概念的。

今天就給大家寫一篇去配置中心需要考慮的點,我也不是什麼配置中心開源專案的參與者,所以寫出來的僅供大家參考。

有必要重複造輪子嗎?

當面試官問你:如果讓你寫一個配置中心,說說你的設計思路? 首先我們要有自己的想法,雖然是在面試過程中的問題。我們也可以反問,市面上目前有幾款很優秀的開源的配置中心,我們可以直接拿來用,有必要去重新造輪子嗎?

如果面試官說只是考察一下你對這塊的設計和理解程度,然後你就可以接著講解你的思路了。如果面試官說我們很多框架都是自研的,任性,就是有這個需求,那你還是得接著說,躲不掉,哈哈。

如果要重新造,我們也可以基於開源的進行改造,下面我說下如果要設計一個配置中心,它的整體思路是怎樣的,需要用到哪些技術點,然後開始你的表演。

配置儲存選型

首先我們來看儲存的選型,配置中心需要儲存所有的配置內容,肯定需要進行儲存。目前主流開源的配置中心都採用 Mysql 進行配置的儲存,當然你也可以用其他的,比如 MongoDB 也非常適合。

用不同的資料庫在設計表結構的時候會有所不同,比如 Mysql 可能要 10 個表,MongoDB 簡化後可能 5 個表就夠了(Mysql 多表關聯,MongoDB 內嵌文件)。

Mysql 多表關聯

MongoDB 內嵌文件

這些表除了基本的配置內容儲存,還有就是一些輔助的表,比如使用者資訊,許可權資訊等。

除了底層結構的設計,我們還需要考慮儲存的可用性。Mysql 可以做主從,分庫分表等,MongoDB 天生就是分散式的資料庫,也不存在單點問題,在可用性這塊都是 OK 的。

另外在設計層面,對於配置資訊可以加上本地快取,當資料庫或者服務不可用時也能短暫提供服務能力,一般都是在 client 層面做。Apollo 和 Nacos 都會在本地快取配置資訊。

配置隔離

配置隔離在配置中心也是非常重要的一個點,不同的環境不同的配置資訊,這個是最基礎的。在沒使用配置中心之前通常都是在專案中為每個環境維護一個配置檔案,然後通過命令進行切換需要使用的檔案。

除了環境的隔離,還有一種就是訪問層面的隔離,比如名稱空間,不同的空間相互是隔離的,不能相互訪問。

底層隔離的方式也有很多種,第一種是在儲存的時候增加一個欄位進行環境的區分,資料統一儲存在一起,但是可以區分,這種方式好處在於一套配置中心可以提供給所有環境進行使用。

第二種是在部署層面直接就隔離了,也就是測試環境部署一套獨立的配置中心,線上也部署一套獨立的配置中心,也就不需要在儲存的時候通過欄位隔離了。

第三種也是部署的時候進行隔離,不同的點在於 Web 後臺管理只部署一套,配置資訊對應的服務可以按環境部署多套,每套都有自己獨立的資料庫,Apollo 就是採用這種方式。

配置推送重新整理

配置在修改後能夠實時的推送到應用程式中進行更新,這個是最重要的一個功能,使用者體驗也是非常好的。在沒用配置中心之前,有用 Mysql 進行配置儲存的,為了提高效能,減小資料庫的壓力,配置資訊讀取後會放入快取中,後臺會啟動一個定時執行緒去更新,比如 1 分鐘一次。

這樣帶來的問題就是配置改完後需要等待一定的時間客戶端才能更新好,一般場景都沒啥問題,對於一些特殊的場景還是需要改完立馬生效,才能儘可能避免某些業務問題帶來的損失。

對於配置修改及時更新的實現方式目前主要分為兩種:推和拉。

拉模式前面講過了,有時間間隔問題,就算設定的很快,比如 1 秒一次,頻率太高會導致服務端壓力過大。

推模式是比較好的方式,當服務端有變動的時候將變更的資訊推送給客戶端,即及時又能減輕定時拉取的頻率。

推送可以採用 Spring DeferredResult 將請求掛起的模式實現,詳情可以參考我的這篇文章:

https://mp.weixin.qq.com/s/h8JrfgLn2NMUXNDFg05qxQ

更好的方式是推拉結合,目前主流的配置中心都是採用這種方式。推保證及時性,拉用於兜底,保證最終配置一致性,推拉結合的模式可以將拉取的時間放長,降低服務端壓力。

整合 Spring

Spring 是 Java 語言開發必不可少的好朋友,使用 Spring 可以極高的提高我們的開發效率,各種框架都能非常方便的整合。

在 Spring 中最常見的兩種獲取配置值的方式是@Value 和@ConfigurationProperties,要想使用上面的方式能夠獲取到配置中心裡的內容,需要在專案啟動的時候從配置中心載入對應的配置內容,然後整合到 Spring 中。

Spring 中提供了 ConfigurableEnvironment,ConfigurableEnvironment 中又包含多個 PropertySource。PropertySource 就是 Key,Value 的配置。所以需要在應用啟動的時候,獲取配置資訊組裝成 PropertySource 交給 Spring 管理。

許可權審計

無論是所有環境用一套配置中心還是每個環境都有單獨的部署,許可權控制還是要的,因為不同的小組負責不同的業務,肯定不能隨便去改動其他組的配置。

另一個場景就是配置能被誰改,這個一般都是負責人進行修改,團隊人員可以檢視配置資訊,這個也是很常見需要進行控制的場景。

單純從配置的功能來講,很多人都會說為什麼我要用配置中心,自己搞張表儲存一下不也行麼,我認為配置的儲存是最基本的功能,更多讓我們使用配置中的原因在於可以節省我們自己去做的成本。同時配置中心具有很全的治理方面的能力,比如許可權,灰度實用的功能等。

指標監控

作為一款中介軟體,而且是被很多系統使用,它的一些效能指標也是需要監控起來的。常見的做法有下面幾種方式。

一種是配置中心自己暴露出一些指標資料,可以讓外部監控系統進行拉取,pull 方式。像 Nacos 中就暴露了 metrics 資料,可以用 prometheus 進行拉取並監控,非常方便。

一種是配置中心自己埋點,對接一些監控系統,採用 push 的方式。比如 Apollo 中就整合了 Cat 的監控,可以將相關監控資料投遞到 Cat 中進行展示並告警。

還有一種方式就是提供 Tracer 相關的 SPI,可以讓使用方自行去接入不同的監控,靈活度更高。

無論用哪種方式,我們的最終目的是一致的,都是為了能夠讓 Bug 不發生,就算有問題也能監控到,不然就慘了,哈哈。

開放 API/多語言 SDK

目前幾款比較活躍的配置中心都是 Java 開發的,也提供了對應的 Java SDK。如果你自己用其他語言開發一套配置中心,也是一樣的需要有對應語言的 SDK。如果公司是多語言技術棧,那麼可以為每種語言都開發一個 SDK 進行接入。

如果作為開源的專案,也不能規定別人使用什麼語言,如果不想開發多語言 SDK 的話,可以提供一套開放 API 讓使用者自己去封裝 SDK 或者直接在專案中進行接入。

關於作者:尹吉歡,簡單的技術愛好者,《Spring Cloud 微服務-全棧技術與案例解析》, 《Spring Cloud 微服務 入門 實戰與進階》作者, 公眾號猿天地發起人。

我整理了一份很全的學習資料,感興趣的可以微信搜尋「猿天地」,回覆關鍵字 「學習資料」獲取我整理好了的 Spring Cloud,Spring Cloud Alibaba,Sharding-JDBC 分庫分表,任務排程框架 XXL-JOB,MongoDB,爬蟲等相關資料。

相關文章