Apollo介紹
Apollo(阿波羅)是攜程框架部門研發(fā)的開源配置管理中心劲弦,能夠集中化管理應用不同環(huán)境、不同集群的配置嘶摊,配置修改后能夠實時推送到應用端仅胞,并且具備規(guī)范的權限、流程治理等特性饺藤。
Apollo支持4個維度管理Key-Value格式的配置:
- application (應用)
- environment (環(huán)境)
- cluster (集群)
- namespace (命名空間)
Apollo的優(yōu)勢
正是基于配置的特殊性包斑,所以Apollo從設計之初就立志于成為一個有治理能力的配置發(fā)布平臺,目前提供了以下的特性:
- 統(tǒng)一管理不同環(huán)境涕俗、不同集群的配置
Apollo提供了一個統(tǒng)一界面集中式管理不同環(huán)境(environment)罗丰、不同集群(cluster)、不同命名空間(namespace)的配置再姑。
同一份代碼部署在不同的集群萌抵,可以有不同的配置,比如zookeeper的地址等
通過命名空間(namespace)可以很方便地支持多個不同應用共享同一份配置,同時還允許應用對共享的配置進行覆蓋
-
配置修改實時生效(熱發(fā)布)
- 用戶在Apollo修改完配置并發(fā)布后绍填,客戶端能實時(1秒)接收到最新的配置萎坷,并通知到應用程序
版本發(fā)布管理
所有的配置發(fā)布都有版本概念,從而可以方便地支持配置的回滾
-
灰度發(fā)布
- 支持配置的灰度發(fā)布沐兰,比如點了發(fā)布后,只對部分應用實例生效蔽挠,等觀察一段時間沒問題后再推給所有應用實例
-
權限管理住闯、發(fā)布審核、操作審計
- 應用和配置的管理都有完善的權限管理機制澳淑,對配置的管理還分為了編輯和發(fā)布兩個環(huán)節(jié)比原,從而減少人為的錯誤。
- 所有的操作都有審計日志杠巡,可以方便地追蹤問題
客戶端配置信息監(jiān)控
可以在界面上方便地看到配置在被哪些實例使用
-
提供Java和.Net原生客戶端
- 提供了Java和.Net的原生客戶端量窘,方便應用集成
- 支持Spring Placeholder, Annotation和Spring Boot的ConfigurationProperties,方便應用使用(需要Spring 3.1.1+)
- 同時提供了Http接口氢拥,非Java和.Net應用也可以方便地使用
-
提供開放平臺API
- Apollo自身提供了比較完善的統(tǒng)一配置管理界面蚌铜,支持多環(huán)境、多數(shù)據(jù)中心配置管理嫩海、權限冬殃、流程治理等特性。不過Apollo出于通用性考慮叁怪,不會對配置的修改做過多限制审葬,只要符合基本的格式就能保存,不會針對不同的配置值進行針對性的校驗奕谭,如數(shù)據(jù)庫用戶名涣觉、密碼,Redis服務地址等
- 對于這類應用配置血柳,Apollo支持應用方通過開放平臺API在Apollo進行配置的修改和發(fā)布官册,并且具備完善的授權和權限控制
-
部署簡單
- 配置中心作為基礎服務,可用性要求非常高混驰,這就要求Apollo對外部依賴盡可能地少
- 目前唯一的外部依賴是MySQL攀隔,所以部署非常簡單,只要安裝好Java和MySQL就可以讓Apollo跑起來
- Apollo還提供了打包腳本栖榨,一鍵就可以生成所有需要的安裝包昆汹,并且支持自定義運行時參數(shù)
Apollo的優(yōu)勢還可以通過與Spring Cloud Config對比來體現(xiàn)出
Apollo的核心概念介紹
Namespace
Namespace就相當于spring boot項目中的配置文件,例如namespace中有默認的application,格式為properties婴栽,則對應著application.properties满粗。
1 Namespace的格式
配置文件有多種格式,例如:properties愚争、xml映皆、yml挤聘、yaml、json等捅彻。同樣Namespace也具有這些格式组去。
2 Namespace的獲取權限分類
Namespace的獲取權限分為兩種:
private (私有的)
public (公共的)
這里的獲取權限是相對于Apollo客戶端來說的。
2.1 private權限
private權限的Namespace步淹,只能被所屬的應用獲取到从隆。一個應用嘗試獲取其它應用private的Namespace,Apollo會報“404”異常缭裆。
2.2 public權限
public權限的Namespace键闺,能被任何應用獲取。
3. Namespace的類型
Namespace類型有三種:
- 私有類型
- 公共類型
- 關聯(lián)類型(繼承類型)
3.1 私有類型
私有類型的Namespace具有private權限澈驼。例如上文提到的“application” Namespace就是私有類型辛燥。
3.2 公共類型
3.2.1 含義
公共類型的Namespace具有public權限。公共類型的Namespace相當于游離于應用之外的配置缝其,且通過Namespace的名稱去標識公共Namespace挎塌,所以公共的Namespace的名稱必須全局唯一。
3.2.2 使用場景
- 部門級別共享的配置
- 小組級別共享的配置
- 幾個項目之間共享的配置
- 中間件客戶端的配置
3.3 關聯(lián)類型
3.3.1 含義
關聯(lián)類型又可稱為繼承類型氏淑,關聯(lián)類型具有private權限勃蜘。關聯(lián)類型的Namespace繼承于公共類型的Namespace,用于覆蓋公共Namespace的某些配置假残。例如公共的Namespace有兩個配置項
k1 = v1
k2 = v2
然后應用A有一個關聯(lián)類型的Namespace關聯(lián)了此公共Namespace缭贡,且覆蓋了配置項k1,新值為v3辉懒。那么在應用A實際運行時阳惹,獲取到的公共Namespace的配置為:
k1 = v3
k2 = v2
Apollo服務端(測試客戶端用)
1 準備工作
1.1
apollo服務端要求1.8+
apollo客戶端要求1.7+
1.2 MySQL
版本要求5.6.5+
1.3 下載Quick Start安裝包
-
從Github下載
- checkout或下載apollo-build-scripts項目
- 由于Quick Start項目比較大,所以放在了另外的repository眶俩,請注意項目地址
-
從百度網(wǎng)盤下載
- 通過網(wǎng)盤鏈接下載莹汤,提取碼:rmq9
- 下載到本地后,在本地解壓apollo-build-scripts-master.zip
2. 安裝步驟
2.1 創(chuàng)建數(shù)據(jù)庫
Apollo服務端共需要兩個數(shù)據(jù)庫:ApolloPortalDB和ApolloConfigDB颠印,數(shù)據(jù)庫纲岭、表的創(chuàng)建和樣例數(shù)據(jù)都分別準備了sql文件,只需要導入數(shù)據(jù)庫即可线罕。
驗證方法:
-
ApolloPortalDB:
select `Id`, `AppId`, `Name` from ApolloPortalDB.App;
-
ApolloConfigDB:
select `NamespaceId`, `Key`, `Value`, `Comment` from ApolloConfigDB.Item;
如果都有查詢出結果那表示數(shù)據(jù)庫創(chuàng)建成功止潮。
2.2 配置數(shù)據(jù)庫連接信息
Apollo服務端需要知道如何連接到你前面創(chuàng)建的數(shù)據(jù)庫,所以需要編輯demo.sh钞楼,修改ApolloPortalDB和ApolloConfigDB相關的數(shù)據(jù)庫連接串信息喇闸。
注意:填入的用戶需要具備對ApolloPortalDB和ApolloConfigDB數(shù)據(jù)的讀寫權限。
# apollo config db info
apollo_config_db_url=jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8
apollo_config_db_username=用戶名
apollo_config_db_password=密碼(如果沒有密碼,留空即可)
# apollo portal db info
apollo_portal_db_url=jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8
apollo_portal_db_username=用戶名
apollo_portal_db_password=密碼(如果沒有密碼燃乍,留空即可)
3 啟動Apollo配置中心
Apollo的quick start腳本會在本地啟動三個端口分別為8070唆樊、8080、8090的服務刻蟹,需在確保端口未被占用的情況下執(zhí)行腳本
./demo.sh start
eg:關閉服務的命令:
./demo.sh stop
當看到如下輸出后逗旁,就說明啟動成功了!
==== starting service ====
Service logging file is ./service/apollo-service.log
Started [10768]
Waiting for config service startup.......
Config service started. You may visit http://localhost:8080 for service status now!
Waiting for admin service startup....
Admin service started
==== starting portal ====
Portal logging file is ./portal/apollo-portal.log
Started [10846]
Waiting for portal startup......
Portal started. You can visit http://localhost:8070 now!
異常排查
如果啟動遇到了異常舆瘪,可以分別查看service和portal目錄下的log文件排查問題痢艺。
注:在啟動apollo-configservice的過程中會在日志中輸出eureka注冊失敗的信息,如com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused介陶。需要注意的是,這個是預期的情況色建,因為apollo-configservice需要向Meta Server(它自己)注冊服務哺呜,但是因為在啟動過程中,自己還沒起來箕戳,所以會報這個錯某残。后面會進行重試的動作,所以等自己服務起來后就會注冊正常了陵吸。
服務端使用
通過訪問http://localhost:8070/可訪問web頁面的服務端玻墅。
初始賬號/密碼為:admin/apollo
具體使用指南可參考官網(wǎng)
該服務端只是用來初步體驗和測試使用。
Apollo的客戶端
Apollo支持基于Spring Boot壮虫、基于Java澳厢、基于XML等等多種方式的配置,具體詳情可參考官網(wǎng)
Apollo會在本地存一份緩存配置文件
- Mac/Linux上文件位置為/opt/data/{appId}/config-cache
- Windows上文件位置為C:\opt\data{appId}\config-cache
- 本地配置文件會以{appId}+{cluster}+{namespace}.properties的文件名和格式存儲囚似,當獲取不到網(wǎng)絡配置時會從這個配置中取值
下面我就介紹最常用剩拢、簡便、快捷饶唤、通用的方式徐伐,即基于Spring Boot的集成方式。
1 首先加入依賴
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.1.0</version>
</dependency>
2 在服務應用的配置中加入以下配置(本例子中的文件為application.yml):
app:
id: test-app
apollo:
meta: http://localhost:8080
#cluster: myCluster
#cacheDir: /opt/testDir
bootstrap:
enable: true
namespaces: application
env: DEV
- app.id為在服務端web頁面上創(chuàng)建的項目APP的id
- apollo.meta為apollo服務端的地址
- apollo.cluster為要配置的集群名稱募狂,如果沒有可不填
- apollo.cacheDir為自定義緩存路徑
- apollo.bootstrap.enable為是否在工程啟動的bootstrap階段向Spring容器注入被托管的namespaces中的配置
- apollo.bootstrap.namespaces為要使用的namespaces办素,可在web頁面上看到
- env為要獲取的配置環(huán)境,目前支持以下幾個值(大小寫不敏感):
- DEV(Development environment)
- FAT(Feature Acceptance Test environment)
- UAT(User Acceptance Test environment)
- PRO(Production environment)
在啟動Spring Boot的java文件中添加注解:
@EnableApolloConfig
Apollo客戶端的使用
通過@Value注解即可獲取到值
-
可以以類的方式作為bean加載入Spring祸穷,例如
@EnableApolloConfig @Configuration Class A { @Bean public getB() { return new B(); } } Class B { private int x; public void setX(int x) { this.x = x; } public int getX() { return this.x; } }