分佈式配置中心Apollo系列--概念及原理介紹

1、Apollo簡介

Apollo(阿波羅)是攜程框架部門研發的開源配置管理中心,能夠集中化管理應用不同環境、不同集羣的配置,配置修改後能夠實時推送到應用端,並且具備規範的權限、流程治理等特性。

Apollo支持4個維度管理Key-Value格式的配置:

  1. application (應用)
  2. environment (環境)
  3. cluster (集羣)
  4. namespace (命名空間)

同時,Apollo基於開源模式開發,開源地址:https://github.com/ctripcorp/apollo

 

2、Why Apollo

Apollo從設計之初就立志於成爲一個有治理能力的配置發佈平臺,目前提供了以下的特性:

  • 統一管理不同環境、不同集羣的配置
    • Apollo提供了一個統一界面集中式管理不同環境(environment)、不同集羣(cluster)、不同命名空間(namespace)的配置。
    • 同一份代碼部署在不同的集羣,可以有不同的配置,比如zookeeper的地址等
    • 通過命名空間(namespace)可以很方便地支持多個不同應用共享同一份配置,同時還允許應用對共享的配置進行覆蓋
  • 配置修改實時生效(熱發佈)
    • 用戶在Apollo修改完配置併發布後,客戶端能實時(1秒)接收到最新的配置,並通知到應用程序
  • 版本發佈管理
    • 所有的配置發佈都有版本概念,從而可以方便地支持配置的回滾
  • 灰度發佈
    • 支持配置的灰度發佈,比如點了發佈後,只對部分應用實例生效,等觀察一段時間沒問題後再推給所有應用實例
  • 權限管理、發佈審覈、操作審計
    • 應用和配置的管理都有完善的權限管理機制,對配置的管理還分爲了編輯和發佈兩個環節,從而減少人爲的錯誤。
    • 所有的操作都有審計日誌,可以方便地追蹤問題
  • 客戶端配置信息監控
    • 可以在界面上方便地看到配置在被哪些實例使用
  • 提供Java和.Net原生客戶端
    • 提供了Java和.Net的原生客戶端,方便應用集成
    • 支持Spring Placeholder, Annotation和Spring Boot的ConfigurationProperties,方便應用使用(需要Spring 3.1.1+)
    • 同時提供了Http接口,非Java和.Net應用也可以方便地使用
  • 提供開放平臺API
    • Apollo自身提供了比較完善的統一配置管理界面,支持多環境、多數據中心配置管理、權限、流程治理等特性。不過Apollo出於通用性考慮,不會對配置的修改做過多限制,只要符合基本的格式就能保存,不會針對不同的配置值進行針對性的校驗,如數據庫用戶名、密碼,Redis服務地址等
    • 對於這類應用配置,Apollo支持應用方通過開放平臺API在Apollo進行配置的修改和發佈,並且具備完善的授權和權限控制
  • 部署簡單
    • 配置中心作爲基礎服務,可用性要求非常高,這就要求Apollo對外部依賴儘可能地少
    • 目前唯一的外部依賴是MySQL,所以部署非常簡單,只要安裝好Java和MySQL就可以讓Apollo跑起來
    • Apollo還提供了打包腳本,一鍵就可以生成所有需要的安裝包,並且支持自定義運行時參數

 

3、Apollo基礎模型

如下即是Apollo的基礎模型:

  1. 用戶在配置中心對配置進行修改併發布
  2. 配置中心通知Apollo客戶端有配置更新
  3. Apollo客戶端從配置中心拉取最新的配置、更新本地配置並通知到應用

 

 

4、總體設計

 

上圖簡要描述了Apollo的總體設計,我們可以從下往上看:

  • Config Service提供配置的讀取、推送等功能,服務對象是Apollo客戶端
  • Admin Service提供配置的修改、發佈等功能,服務對象是Apollo Portal(管理界面)
  • Config Service和Admin Service都是多實例、無狀態部署,所以需要將自己註冊到Eureka中並保持心跳
  • 在Eureka之上我們架了一層Meta Server用於封裝Eureka的服務發現接口
  • Client通過域名訪問Meta Server獲取Config Service服務列表(IP+Port),而後直接通過IP+Port訪問服務,同時在Client側會做load balance、錯誤重試
  • Portal通過域名訪問Meta Server獲取Admin Service服務列表(IP+Port),而後直接通過IP+Port訪問服務,同時在Portal側會做load balance、錯誤重試
  • 爲了簡化部署,我們實際上會把Config Service、Eureka和Meta Server三個邏輯角色部署在同一個JVM進程中

 

5、客戶端設計.

 

上圖簡要描述了Apollo客戶端的實現原理:

  1. 客戶端和服務端保持了一個長連接,從而能第一時間獲得配置更新的推送。
  2. 客戶端還會定時從Apollo配置中心服務端拉取應用的最新配置。
    • 這是一個fallback機制,爲了防止推送機制失效導致配置不更新
    • 客戶端定時拉取會上報本地版本,所以一般情況下,對於定時拉取的操作,服務端都會返回304 - Not Modified
    • 定時頻率默認爲每5分鐘拉取一次,客戶端也可以通過在運行時指定System Property: apollo.refreshInterval來覆蓋,單位爲分鐘。
  1. 客戶端從Apollo配置中心服務端獲取到應用的最新配置後,會保存在內存中
  2. 客戶端會把從服務端獲取到的配置在本地文件系統緩存一份
    • 在遇到服務不可用,或網絡不通的時候,依然能從本地恢復配置
  1. 應用程序從Apollo客戶端獲取最新的配置、訂閱配置更新通知

 

5.1 配置更新推送實現:

 

前面提到了Apollo客戶端和服務端保持了一個長連接,從而能第一時間獲得配置更新的推送。

長連接實際上我們是通過Http Long Polling實現的,具體而言:

  • 客戶端發起一個Http請求到服務端
  • 服務端會保持住這個連接60秒
    • 如果在60秒內有客戶端關心的配置變化,被保持住的客戶端請求會立即返回,並告知客戶端有配置變化的namespace信息,客戶端會據此拉取對應namespace的最新配置
    • 如果在60秒內沒有客戶端關心的配置變化,那麼會返回Http狀態碼304給客戶端
  • 客戶端在收到服務端請求後會立即重新發起連接,回到第一步

考慮到會有數萬客戶端向服務端發起長連,在服務端我們使用了async servlet(Spring DeferredResult)來服務Http Long Polling請求。

 

6、可用性考慮:

配置中心作爲基礎服務,可用性要求非常高,下面的表格描述了不同場景下Apollo的可用性:

場景

影響

降級

原因

某臺config service下線

無影響

 

Config service無狀態,客戶端重連其它config service

所有config service下線

客戶端無法讀取最新配置,Portal無影響

客戶端重啓時,可以讀取本地緩存配置文件

 

某臺admin service下線

無影響

 

Admin service無狀態,Portal重連其它admin service

所有admin service下線

客戶端無影響,portal無法更新配置

   

某臺portal下線

無影響

 

Portal域名通過slb綁定多臺服務器,重試後指向可用的服務器

全部portal下線

客戶端無影響,portal無法更新配置

   

某個數據中心下線

無影響

 

多數據中心部署,數據完全同步,Meta Server/Portal域名通過slb自動切換到其它存活的數據中心

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章