1. 程式人生 > 其它 >華為雲物聯網高階攻城獅的4年配置中心實踐分享

華為雲物聯網高階攻城獅的4年配置中心實踐分享

摘要:4年期間經歷了自研配置中心到 Apollo 再到自研配置中心和 Apollo 並存的場景,本文總結了一下這幾年的配置中心演進流程。

本文分享自華為雲社群《華為雲物聯網高階攻城獅的4年配置中心實踐分享》,作者:華為雲IoT高階工程師 賀張儉。

自 17 年入職華為之後,一直在使用配置中心,4年期間經歷了自研配置中心到 Apollo 再到自研配置中心和 Apollo 並存的場景。總結了一下這幾年的配置中心演進流程,想把我們在配置中心上的一些實踐分享給大家,實現共同進步。Apollo 是一款非常優秀的開源軟體,如果對 Apollo 存在理解錯誤,還望大家不吝賜教,謝謝。

Apollo(阿波羅)是一款開源配置管理中心,能夠集中化管理應用不同環境、不同叢集的配置,配置修改後能夠實時推送到應用端,並且具備規範的許可權、流程治理等特性,適用於微服務配置管理場景。

Github:https://github.com/apolloconfig/apollo

1 使用到的配置分類

1.1 從場景分類

1.1.1 運維配置,即程式只讀的配置

人工配置。通過人工在配置中心介面進行配置,而程式只進行讀取,如資料庫配置、郵箱伺服器配置、網絡卡配置、子網地址配置等。這部分配置資料不要求程式碼動態寫入。

1.1.2 業務配置,即程式可寫的配置

我們是一個 SaaS 服務,每個使用者在上面都有一些業務配置。如使用者的證書配置、使用者伺服器的流控配置等,這些業務配置相對運維配置來說更加複雜,且可能會有唯一性限制,如按使用者 id 唯一。這部分配置資料一般由使用者操作觸發,程式碼動態寫入,並且通知到各個微服務例項。通常,我們希望這些配置能在介面展示,且支援人為修改。上述邏輯如果由各微服務自己實現,會存在大量重複程式碼,並且質量無法保證。我們希望由一個公共元件來統一實現這個能力。

1.2 從配置是否會有列表可分為單值配置或多值配置

1.2.1 單值配置

整個配置下只是多對 key、value。value 不是很複雜的格式,往往是整數或字串。

1.2.2 多值配置

多值配置更加複雜,往往是單值配置在不同的 key 下,有不同的值。比如下面的配置,使用者一和使用者二的執行緒池大小和佇列不同

2 第一階段自研配置中心

在做雲服務之前,我們的配置中心層級數較少。我們以軟體的形式交付給客戶,軟體執行時分為管理面和業務面,配置中心管理著管理面和業務面的配置,最為複雜的場景是多套業務面,這個時候需要保證不同叢集、不同微服務下的配置不衝突,配置層級為叢集、微服務、配置。

此時的配置中心是完全自研的,不包含藍綠、灰度配置這些功能,它獨具特色的地方有以下兩點:

2.1 單配置單表

  • 在儲存模型上,每個配置對應一張資料表。
  • 對多值配置比較友好,尤其是複雜業務配置,可以支援各種主鍵約束。對單值配置,稍微重型了一些。
  • 配置的強 Schema 限制。這些限制包括型別、大小、長度、是否敏感等限制。這種限制既能為介面修改配置提供良好的體驗(如:不同格式不同的輸入框、敏感欄位,前臺輸入明文,後臺入庫加密等),也能在通過介面寫入配置時做充分的校驗。

2.2 通過回撥方式來確保配置的可靠

舉個例子,新增一個配置的流程是這樣的

可能這裡,有讀者想要問了,這個流程能確保什麼可靠呢。這個流程通過呼叫微服務介面來校驗配置是否可靠,如 IP 地址是否合法、對端地址是否可達、配置數量是否超過規格等等,來保證配置基本可用。

總的來說,這個自研的配置中心在當時綜合體驗還是不錯的。但是也有一些問題有待改進,比如單配置下配置項數量過多時,因為底層有部分介面單配置下所有資料都通過一個 http 請求來承載,會導致響應超時等問題。

3 第二階段 Apollo

開始第二階段實踐的原因主要是,我們進行了組織切換,業務重心轉向做雲服務,同時團隊進行 DevOps 轉型。原先的老配置中心是由另一個團隊維護的,組織切換完之後,如果還要使用,就要我們自己維護。所以我們需要在繼續維護老配置中心和引入開源 Apollo 中間進行選擇。除了上文中提到的運維配置和業務配置,這個時候我們的需求還有改變:

  • 配置的層級愈發豐富了
  • 要構建灰度釋出微服務的能力

老配置中心一方面由於組織切換原因不提供維護了,另一方面不能支撐豐富的配置層級,也不具備灰度釋出的能力。這個時候,Apollo 的一些特性吸引了我們,這些特性正是老配置中心所缺乏的,例如(部分引用自 Apollogithub 主頁)

  • 豐富的層級,從 app_id 到 cluster,namespace,key-value 的層級能滿足我們 region、叢集、微服務的層級訴求;
  • 支援配置的灰度釋出,比如點了釋出後,只對部分應用例項生效,等觀察一段時間沒問題後再推給所有應用例項;
  • 所有的配置釋出都有版本概念,從而可以方便的支援配置的回滾;
  • 應用和配置的管理都有完善的許可權管理機制,對配置的管理還分為了編輯和釋出兩個環節,從而減少人為的錯誤;
  • 所有的操作都有審計日誌,可以方便的追蹤問題。

因此我們選型引入了 Apollo,我和我的主管,還有一個其他同事參與了這項工作。我們在 Apollo 開原始碼的基礎上做了比較大的改動,主要原因有以下幾點:

  • 節約成本,將註冊中心、資料庫替換成我們當前正在使用的元件,因為這兩個依賴不是 Apollo 的核心依賴
  • 繼承老配置中心強 Schema 的優點
  • 保留回撥確認配置的流程,提前攔截錯誤的配置,降低程式碼處理異常配置的複雜度
  • 通過 spi 或環境變數的方式相容存量老局點使用老配置中心的場景

結合上述原因,我們最終是這麼實踐的:

  • 資料庫切換為 postgre 資料庫、註冊中心切換到 servicecomb
  • 在 namespace 上實現了 Schema,每個 namespace 都可以註冊對應的 Schema,Schema 要求資料必須是 json 格式,且 json 內對應的 value 必須滿足 Schema 定義的規範(如 ip 地址、小數、整數等)

Schema 舉例:

[
    {
         "name":"name",
         "type":"string"
    },
    {
         "name":"age",
         "type":"int",
         "max":120
    },
    {
         "name":"ip",
         "type":"ipv4"
    }
]

那麼資料應該是這樣的:

{
     "name":"hezhangjian",
     "age":23,
     "ip":"127.0.0.1"
}
  • 在新增或修改配置的時候,實現了回撥功能,由回撥業務服務確認配置能否新增或修改;
  • 配置分層:雲服務對應 Apollo 的 app_id,把內部的環境對應到 Apollo 上的叢集,然後將微服務名+配置名拼接成配置名稱。

下圖展示了業務概念和 Apollo 概念的對應關係,有些配置是單值配置,有些是多值配置,所以配置項這一層級是可選的。

在這段時間的實踐中,我們也發現瞭如下的一些問題。

3.1 併發問題

其中最致命的就是併發問題,首先 Apollo 所有配置都存在一張表中,其次由於 Apollo 設計之初主要考慮的是運維人員手動在介面上操作,程式碼無併發語義(或者說沒給客戶端併發語義),使得我們通過程式碼寫入配置時難以解決併發問題。

3.2 效能問題

開啟 namespace 列表頁面,需要顯示這個 app_id 下的所有 namespace,因為我們單 app_id 會存放單個雲服務的所有配置,這個量很大,且介面不支援分頁,導致頁面載入緩慢。

3.3 體驗問題

Apollo 的 namespace 介面未提供搜尋功能(可能 Apollo 設計之初也沒想支援這麼多),想要從 namespace 中定位到我們想要檢視或修改的 namespace,只能藉助瀏覽器的搜尋能力。

4 第三階段 Apollo 與自研配置中心並存

除了上述幾個問題,還有一些原因使得我們開始了第三階段的實踐:

  • 原來自上而下的配置分層模型,微服務間配置沒隔離,不僅不易進行許可權管理,而且不適合 DevOps 單微服務自治的釋出理念;
  • 第二階段對 Apollo 改動太多,組織結構變動,沒有足夠的人力維護;
  • 隨著叢集越來越多,回撥功能需要網路的雙向打通,網路維護不太方便;
  • 我們對 Apollo 介面以及介面基於業務做的改動較多,導致其他兄弟部門難以共用 Apollo

當時大家對是否保留 Schema、回撥檢查、程式碼寫配置這三個功能點有較大的爭議。我個人最希望保留 Schema、回撥檢查,因為它們優點顯著,而且介面是相容的,可以與其他部門共用,但是增加了 Schema 這個概念和回撥檢查這個流程,會增加學習成本。而程式碼寫配置,由於要解決併發問題,程式碼改動量較大,我不建議保留。

大家經過激烈的討論,最終還是廢棄了 Schema、回撥檢查、程式碼寫配置這三個功能點,僅僅把運維配置放在 Apollo。

然後,我們把業務配置,放在了一個自研的強 Schema 的配置中心上,這個配置中心,僅負責單叢集的配置,每個叢集部署一套,滿足了我們的業務需求。自研強 Schema 配置中心的核心要點有,單配置單表、通過註冊中心回撥來檢測配置是否合法、藉助 mqtt 協議來實現長連結推送,無單點瓶頸。

而我們的運維配置中心 Apollo 迴歸到了開源的版本,重整了配置的結構,

對運維配置而言好處有:

  • 配置模型適合單微服務釋出;
  • 配置按微服務組織,一個頁面上的 namespace 不會很多。

缺點:

  • Schema 缺失後,不會對操作人員在介面的配置進行校驗,即使配置格式或者內容錯誤也能配置成功。介面上配置密碼不支援明文(Apollo 無法感知是否為敏感欄位),必須提前使用其他工具將明文轉換為密文,然後再進行配置;
  • 回撥檢查功能去掉後,有些配置,如網絡卡網段配錯,操作人員不能即時得到響應。

4.1 最佳實踐

業務配置經過我們的實踐,確實不適合使用開源的 Apollo。運維配置使用原生的 Apollo,但是現在還不具備回撥檢查和 Schema 的功能,希望 Apollo 能在後續版本中支援 Schema,或者弱化的 json 格式檢查功能。下面是我們在如下場景下的最佳實踐。

4.1.1 SRE 在介面上的運維配置

通過 Apollo 來實現功能,至於配置如何組織,根據大家的組織結構、技術架構來對應 Apollo 上的概念,可按照微服務->部署環境或部署環境->微服務的層級來組織配置。

4.1.2 複雜的引數校驗

建議在 Apollo 上面自建 portal 包裹一層,後端服務可先進行一層處理,這一層處理可以做比較複雜的格式化校驗甚至回撥檢查,再呼叫 Apollo OpenApi 將配置寫入 Apollo。

4.1.3 業務配置的技術選型

最大的挑戰是業務配置由使用者觸發,請求的併發不易處理。思路有兩個,一個是在 Apollo 原生程式碼的基礎上,通過資料庫分散式鎖來解決併發問題。第二個是借鑑我們的思路,通過單配置單表、mqtt 協議實現通知等核心技術點,自研業務配置中心。

4.1.4 業務配置的部署

需要根據業務配置的數量來考慮是否合設業務配置中心。單叢集場景下,毫無疑問只需要一個業務配置中心,甚至如果使用 Apollo 實現,可以考慮和運維配置中心合設。多叢集場景下,部署一個業務配置中心,還是多個業務配置中心,我們自己的實踐中,一個叢集往往要支撐數萬使用者,我們採取了每個業務叢集部署一套業務配置中心的策略。

更多學習內容,請前往IoT物聯網社群 

 

點選關注,第一時間瞭解華為雲新鮮技術~