隨着業務的發展、微服務架構的升級,服務的數量、程序的配置日益增多(各種微服務、各種服務器地址、各種參數),傳統的配置文件方式和數據庫的方式已無法滿足開發人員對配置管理的要求:
- 安全性:配置跟隨源代碼保存在代碼庫中,容易造成配置泄漏。
- 時效性:修改配置,需要重啟服務才能生效。
- 局限性:無法支持動態調整:例如日志開關、功能開關。
因此,分布式配置中心應運而生!
開源項目
關於分布式配置中心,網上已經有很多開源的解決方案,例如:
Apollo
Apollo(阿波羅)是攜程框架部門研發的分布式配置中心,能夠集中化管理應用不同環境、不同集群的配置,配置修改后能夠實時推送到應用端,並且具備規范的權限、流程治理等特性,適用於微服務配置管理場景。
項目地址:https://github.com/ctripcorp/apollo
Diamond
Diamond是淘寶研發的分布式配置管理系統。使用Diamond可以讓集群中的服務進程動態感知數據的變化,無需重啟服務就可以實現配置數據的更新。
項目地址:https://github.com/gzllol/diamond
Disconf
專注於各種「分布式系統配置管理」的「通用組件」和「通用平台」, 提供統一的「配置管理服務」
項目地址:https://github.com/knightliao/disconf
項目對比
綜合對比,覺得攜程的Apollo 功能強大完善,github上開源社區比較活躍,代碼一直在維護,而且文檔寫得清楚,故最終選擇Apollo 作為我們的分布式配置中心。下面簡要介紹下Apollo項目。
Apollo簡介
Apollo(阿波羅)是攜程框架部門研發的分布式配置中心,能夠集中化管理應用不同環境、不同集群的配置,配置修改后能夠實時推送到應用端,並且具備規范的權限、流程治理等特性,適用於微服務配置管理場景。
服務端基於Spring Boot和Spring Cloud開發,打包后可以直接運行,不需要額外安裝Tomcat等應用容器。
Java客戶端不依賴任何框架,能夠運行於所有Java運行時環境,同時對Spring/Spring Boot環境也有較好的支持。
.Net客戶端不依賴任何框架,能夠運行於所有.Net運行時環境。
特性
- 統一管理不同環境、不同集群的配置
- 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還提供了打包腳本,一鍵就可以生成所有需要的安裝包,並且支持自定義運行時參數
發布配置
通過配置中心發布配置:
填寫發布信息:
客戶端獲取配置(Java API樣例)
配置發布后,就能在客戶端獲取到了,以Java為例,獲取配置的示例代碼如下。Apollo客戶端還支持和Spring整合,更多客戶端使用說明請參見Java客戶端使用指南和.Net客戶端使用指南。
Config config = ConfigService.getAppConfig();
Integer defaultRequestTimeout = 200;
Integer requestTimeout = config.getIntProperty("requestTimeout", defaultRequestTimeout);
客戶端監聽配置變化
通過上述獲取配置代碼,應用就能實時獲取到最新的配置了。
不過在某些場景下,應用還需要在配置變化時獲得通知,比如數據庫連接的切換等,所以Apollo還提供了監聽配置變化的功能,Java示例如下:
Config config = ConfigService.getAppConfig();
config.addChangeListener(new ConfigChangeListener() {
@Override
public void onChange(ConfigChangeEvent changeEvent) {
for (String key : changeEvent.changedKeys()) {
ConfigChange change = changeEvent.getChange(key);
System.out.println(String.format(
"Found change - key: %s, oldValue: %s, newValue: %s, changeType: %s",
change.getPropertyName(), change.getOldValue(),
change.getNewValue(), change.getChangeType()));
}
}
});
Spring集成樣例
Apollo和Spring也可以很方便地集成,只需要標注@EnableApolloConfig后就可以通過@Value獲取配置信息:
@Configuration
@EnableApolloConfig
public class AppConfig {}
@Component
public class SomeBean {
//timeout的值會自動更新
@Value("${request.timeout:200}")
private int timeout;
}
總結
本文主要介紹和對比了幾種開源分布式配置中心的選型,並重點介紹了下我們最終選擇的攜程Apollo(阿波羅)分布式配置中心的特性和簡單使用,有興趣的讀者可以到具體項目的官網進行詳細研究。