淺析Apollo配置中心
Labs 導讀
隨著程序功能的日益復雜,程序的配置日益增多。各種功能的開關、參數的配置、服務器的地址等,對程序的配置提出了更高的要求,比如,配置修改后實時生效,灰度發布,分環境、分集群管理配置,完善的權限、審核機制等。SpringBoot項目大多使用@Value注解或者@ConfigurationProperties注解讀取配置信息,線上項目經常需要對某些配置進行調整。
Part 01、 為什么需要配置中心
- 配置實時生效
傳統的靜態配置方式要想修改某個配置,只能修改之后重新發布應用,要實現動態性,可以選擇使用數據庫,通過定時輪詢訪問數據庫來感知配置的變化。輪詢頻率低感知配置變化的延時就長,輪詢頻率高,感知配置的變化延時就短,但比較損耗性能,需要在實時性和性能之間做折中。配置中心專門針對這個業務場景,兼顧實時性和一致性來管理動態配置。
- 配置管理流程
配置的權限管理、灰度發布、版本管理、格式校驗和安全配置等一系列配置管理相關的特性也是配置中心不可或缺的一部分。
Part 02、 什么是Apollo
Apollo(阿波羅)是一款可靠的分布式配置管理中心,誕生于攜程框架研發部,能夠集中化管理應用不同環境、不同集群的配置,配置修改后能夠實時推送到應用端,并且具備規范的權限、流程治理等特性,適用于微服務配置管理場景。
Part 03、 功能介紹
? 統一管理不同環境、不同集群的配置
- Apollo提供了一個統一界面集中式管理不同環境(environment)、不同集群(cluster)、不同命名空間(namespace)的配置。
- 同一份代碼部署在不同的集群,可以有不同的配置,比如zk的地址等。
- 通過命名空間(namespace)可以很方便的支持多個不同應用共享同一份配置,同時還允許應用對共享的配置進行覆蓋。
- 配置界面支持多語言(中文,English)。
? 配置修改實時生效(熱發布)
- 用戶在Apollo修改完配置并發布后,客戶端能實時(1秒)接收到最新的配置,并通知到應用程序。
? 版本發布管理
- 所有的配置發布都有版本概念,從而可以方便的支持配置的回滾。
? 灰度發布
- 支持配置的灰度發布,比如點了發布后,只對部分應用實例生效,等觀察一段時間沒問題后再推給所有應用實例。
? 權限管理、發布審核、操作審計
- 應用和配置的管理都有完善的權限管理機制,對配置的管理還分為了編輯和發布兩個環節,從而減少人為的錯誤。
- 所有的操作都有審計日志,可以方便的追蹤問題。
? 客戶端配置信息監控
- 可以方便的看到配置在被哪些實例使用。
? 提供Java和.Net原生客戶端
- 提供了Java和.Net的原生客戶端,方便應用集成。
- 支持Spring Placeholder,Annotation和Spring Boot的ConfigurationProperties,方便應用使用(需要Spring 3.1.1+)。
- 同時提供了Http接口,非Java和.Net應用也可以方便的使用。
? 提供開放平臺API
- Apollo自身提供了比較完善的統一配置管理界面,支持多環境、多數據中心配置管理、權限、流程治理等特性。
- 不過Apollo出于通用性考慮,對配置的修改不會做過多限制,只要符合基本的格式就能夠保存。
- 在我們的調研中發現,對于有些使用方,它們的配置可能會有比較復雜的格式,如xml, json,需要對格式做校驗。
- 還有一些使用方如DAL,不僅有特定的格式,而且對輸入的值也需要進行校驗后方可保存,如檢查數據庫、用戶名和密碼是否匹配。
- 對于這類應用,Apollo支持應用方通過開放接口在Apollo進行配置的修改和發布,并且具備完善的授權和權限控制。
? 部署簡單
- 配置中心作為基礎服務,可用性要求非常高,這就要求Apollo對外部依賴盡可能地少。
- 目前唯一的外部依賴是MySQL,所以部署非常簡單,只要安裝好Java和MySQL就可以讓Apollo跑起來。
- Apollo還提供了打包腳本,一鍵就可以生成所有需要的安裝包,并且支持自定義運行時參數。
Part 04、 架構設計
4.1 基礎模型
如下即是Apollo的基礎模型:
- 用戶在配置中心對配置進行修改并發布。
- 配置中心通知Apollo客戶端有配置更新。
- Apollo客戶端從配置中心拉取最新的配置、更新本地配置并通知到應用。
圖片
4.2 架構模塊
如下即是Apollo架構模塊的概覽:
- Portal:英文意思為門戶,在架構中充當的角色為管理端,用戶通過該模塊對配置進行修改。
- PortalDB:存儲一些環境變量、配置環境等信息的數據庫。注意,該庫不存儲配置信息。
- Admin Service:負責接收Portal發送過來的配置信息,對配置信息進行修改。
- ConfigDB:儲存配置信息的數據庫。
- Client:配置信息使用者,通常為微服務。
- Config Service:負責定期從數據庫(ConfigDB)中拉取配置信息,若有變化,推送給客服端。或是客戶端定期利用該服務拉取配置信息。
- Eureka:注冊中心,無論Conifg Service還是Admin Service,在實際使用中都是部署在多臺服務器上的。因此,對于客戶端或者門戶管理端而言,建立兩個服務的連接都需要通過注冊中心發現服務地址后再連接。
- Meta Service:從Eureka獲取Config Service和Admin Service的服務信息,相當于是一個Eureka Client,增設一個Meta Server的角色主要是為了封裝服務發現的細節,對Portal和Client而言,永遠通過一個Http接口獲取Admin Service和Config Service的服務信息,而不需要關心背后實際的服務注冊和發現組件。
圖片
Part 05、 服務端設計
在配置中心中,一個重要的功能就是配置發布后實時推送到客戶端。下圖即是配置發布后的實時推送設計:
1.用戶在Portal操作配置發布。
2.Portal調用Admin Service的接口操作發布。
3.Admin Service發布配置后,發送ReleaseMessage給各個Config Service。
4.Config Service收到ReleaseMessage后,通知對應的客戶端。
Part 06、 客戶端設計
下圖描述了Apollo客戶端的實現原理:
1.客戶端和服務端保持了一個長連接,從而能第一時間獲得配置更新的推送(通過Http Long Polling實現)。
2.客戶端還會定時從Apollo配置中心服務端拉取應用的最新配置。
a.這是一個fallback機制,為了防止推送機制失效導致配置不更新。
b.客戶端定時拉取會上報本地版本,所以一般情況下,對于定時拉取的操作,服務端都會返回304 - Not Modified。
c.定時頻率默認為每5分鐘拉取一次,客戶端也可以通過在運行時指定System Property: apollo.refreshInterval來覆蓋,單位為分鐘。
3.客戶端從Apollo配置中心服務端獲取到應用的最新配置后,會保存在內存中。
4.客戶端會把從服務端獲取到的配置在本地文件系統緩存一份。
a.在遇到服務不可用,或網絡不通的時候,依然能從本地恢復配置。
5.應用程序可以從Apollo客戶端獲取最新的配置、訂閱配置更新通知。
Part 07、 結束語
在“約定優于配置,配置優于編碼”的開發理念下,通過Apollo配置中心,程序員不需要每次更改線上配置都要重新發布服務,成功實現了將配置與編碼解耦,為線上服務變更配置提供了解決方案。