攜程阿波羅(Apollo)
https://www.cnblogs.com/xiaxiaolu/p/10025597.html
一、瞎扯點什么
1.1 阿波羅
阿波羅是希臘神話中的光明之神、文藝之神,同時也是羅馬神話中的太陽神;他是光明之神,從不說謊,光明磊落,在其身上找不到黑暗,也被稱作真理之神。他非常聰明,通曉世事,是預言之神。
后世各種各樣的項目都喜歡以阿波羅命名,比如著名的美國登月計划:阿波羅計划;
既然攜程以阿波羅(Apollo)命名項目,那我們我們接下來看看,攜程阿波羅能給我們程序員帶來怎樣的光明(我希望這個光明是可以每天下午6點鍾的太陽 哈哈);
下面看看.net core和Apollo會碰撞出什么樣的火花吧
二、攜程阿波羅(Apollo)
2.1簡單介紹
在這之前,我們先看官方是怎么介紹的:
Apollo(阿波羅)是攜程框架部門研發的分布式配置中心,能夠集中化管理應用不同環境、不同集群的配置,配置修改后能夠實時推送到應用端,並且具備規范的權限、流程治理等特性,適用於微服務配置管理場景。
講的很清楚,攜程阿波羅(后面簡稱Apollo)是一個分布式的配置中心,就是管理配置程序配置地方;Apollo服務端基於Spring Boot和Spring Cloud開發(對的,就是微服務框架),打包后可以直接運行,不需要額外安裝Tomcat等應用容器。
Apollo有以下特點:
統一管理不同環境、不同集群的配置
配置修改實時生效(熱發布)
版本發布管理
灰度發布
權限管理、發布審核、操作審計
客戶端配置信息監控
提供Java和.Net原生客戶端
提供開放平台API
部署簡單
具體每一項展開是什么意思,我就不多說了,更多介紹請看Apollo配置中心介紹
再多說一句,截止到這篇博客編寫時間為止,Apollo在github已經有9300+個star了;
並擁有眾多的生產使用案例;
2.2使用場景
我們設想一下,我們微服務架構中,我們一個每一個服務都可能部署到5~10機器上,我們有很幾十個各種各樣的服務;比如某一天,我們機房因為網絡問題,必須更換數據庫服務器ip,業務接口ip等;如果人工去一台機一台機地改,哇,那就就頭痛了。。。
不止是微服務,做開發這么多年,經常因配置的問題引發生產環境的bug。有些年久的項目,幾百個密密麻麻的配置項,經常容易搞混,有時好幾個項目有好多同樣的配置項,經常被配置問題,或者配置衍生的問題搞得奄奄一息;這時候或者選用一個配置管理中心,也是個不錯的選擇;
有人說,我做了用了Jenkins或者什么做了自動化部署的,不是提交一下代碼就可以了嗎;確實,自動化部署環境確實也可以做到配置的“一處更改,所有引用起效”的效果;但是,鏡像的打包失敗,打包時間過長等問題,也需要考慮進來的;
所以,綜合來說,在配置人工管理困難的時候或者說成本較高的時候;使用配置中心是一個合理的選擇;
img
三、Apollo的安裝與配置
3.1 環境
windows10 64bit 專業版
8G內存
這次是我的本地環境,不是騰訊雲了
3.2 安裝
我也在學習中,演示的是本地測試環境的安裝與配置,生產環境請參考分布式部署指南;
我這里是普通方式的安裝,docker方式請參考Apollo Quick Start Docker部署
1、依次安裝以下程序
Java 1.8+
Mysql 5.6.5+ (Apollo的表結構對timestamp使用了多個default聲明,所以需要5.6.5以上版本。)
GitBash (安裝參考)
下載apollo-build-scripts項目到本地
2、創建數據庫
分別執行下面兩個初始化的數據庫sql:
apolloconfigdb.sql
apolloportaldb.sql
執行完成我們得到:
1542806085229
3、修改配置文件
修改剛剛下載項目apollo-build-scripts根目錄下面的demo.sh
!/bin/bash
apollo config db info
apollo_config_db_url=jdbc:mysql://139.199.196.67:3306/ApolloConfigDB?characterEncoding=utf8
apollo_config_db_username=root
apollo_config_db_password=password
apollo portal db info
apollo_portal_db_url=jdbc:mysql://139.199.196.67:3306/ApolloPortalDB?characterEncoding=utf8
apollo_portal_db_username=root
apollo_portal_db_password=password
4、啟動
gitbash執行:
./demo.sh start
靜候片刻,看到以下表示啟動成功(不一定一模一樣):
1543245209761
注意檢查數據庫配置,確認無誤后執行demo.sh,如果有報錯多執行兩次看看,因為我也有
“Config service failed to start in 120 seconds! Please check ./service/apollo-service.log for more information.”
這個報錯,然后再次執行才啟動成功的;
接着如提示訪問 http://127.0.0.1:8070
1542792843089
ok,我們登錄看看,默認賬號密碼是:apollo/admin
我們看到已經有一個SampleApp,作為配置參考了
1542808265590
1542808341712
根據提示,我們再訪問一下 8080 端口:
我知道 Eureka 是java那邊比較喜歡用的服務注冊中心,是一個跟consul差不多一樣的東西,我也不太熟,先放着;
到這一步,Apollo我們已經安裝成功了;接下來我們先參照SampleApp添加一個我們自己的app,為.net core程序的與她的親密接觸做准備;
1542808483430
四、創建/配置Apollo項目
4.1 新建項目
創建一個叫myDotnet的項目
部門數據在ApolloPortalDB庫ServerConfig表里配置
1542809520034
提交后我們看到如下提示,什么是Namespace??擦 需要補課;
1542814456082
4.2 什么是Namespace
官方Apollo核心概念之Namespace已經講得很清楚了。這里是我的理解,看看能不能概括一下:
Apollo每一個項目下面都可以有多個Namespace,每一個Namespace都類似於我們開發中的一個配置文件。比如appsetting.json
Namespace有兩種權限(對客戶端讀取設置的權限):
private:只能被所屬的應用獲取到,像放在當前運行程序目錄下的配置;
public:共有的配置,能被所有的引用獲取到。像放在共享目錄的配置;
Namespace有三種類型(歸類,給不同的歸類設置不同的權限屬性):
私有類型:私有類型的Namespace具有上訴的private權限。
公共類型:公共類型的Namespace具有上訴public權限,即任何應用都可獲取;
關聯類型(繼承類型):比如我們經常配置的timeout,公共配置timeout=60;,然后我本地可以配置的一個timeout=90;覆蓋公共配置這種情景;
4.2.2 示例
如下圖所示,有三個應用:應用A、應用B、應用C。
應用A有兩個私有類型的Namespace:application和NS-Private,以及一個關聯類型的Namespace:NS-Public。
應用B有一個私有類型的Namespace:application,以及一個公共類型的Namespace:NS-Public。
應用C只有一個私有類型的Namespace:applicationNamespaceä¾å
2.2.1 應用A獲取Apollo配置
//application
Config appConfig = ConfigService.getAppConfig();
appConfig.getProperty("k1", null); // k1 = v11
appConfig.getProperty("k2", null); // k2 = v21
//NS-Private
Config privateConfig = ConfigService.getConfig("NS-Private");
privateConfig.getProperty("k1", null); // k1 = v3
privateConfig.getProperty("k3", null); // k3 = v4
//NS-Public,覆蓋公共類型配置的情況,k4被覆蓋
Config publicConfig = ConfigService.getConfig("NS-Public");
publicConfig.getProperty("k4", null); // k4 = v6 cover
publicConfig.getProperty("k6", null); // k6 = v6
publicConfig.getProperty("k7", null); // k7 = v7
2.2.2 應用B獲取Apollo配置
//application
Config appConfig = ConfigService.getAppConfig();
appConfig.getProperty("k1", null); // k1 = v12
appConfig.getProperty("k2", null); // k2 = null
appConfig.getProperty("k3", null); // k3 = v32
//NS-Private,由於沒有NS-Private Namespace 所以獲取到default value
Config privateConfig = ConfigService.getConfig("NS-Private");
privateConfig.getProperty("k1", "default value");
//NS-Public
Config publicConfig = ConfigService.getConfig("NS-Public");
publicConfig.getProperty("k4", null); // k4 = v5
publicConfig.getProperty("k6", null); // k6 = v6
publicConfig.getProperty("k7", null); // k7 = v7
2.2.3 應用C獲取Apollo配置
//application
Config appConfig = ConfigService.getAppConfig();
appConfig.getProperty("k1", null); // k1 = v12
appConfig.getProperty("k2", null); // k2 = null
appConfig.getProperty("k3", null); // k3 = v33
//NS-Private,由於沒有NS-Private Namespace 所以獲取到default value
Config privateConfig = ConfigService.getConfig("NS-Private");
privateConfig.getProperty("k1", "default value");
//NS-Public,公共類型的Namespace,任何項目都可以獲取到
Config publicConfig = ConfigService.getConfig("NS-Public");
publicConfig.getProperty("k4", null); // k4 = v5
publicConfig.getProperty("k6", null); // k6 = v6
publicConfig.getProperty("k7", null); // k7 = v7
仔細看完示例應該理解了,如果實在不了解,我們后面用示例自己去體會;
4.3 添加Namespace和配置項
我們在上面的myDotnet項目下面,分別添加一個Public類型的Namespace和一個Private類型的Namespace;
其中:
Hei.Public:Public類型,存放Mongodb連接,Redis連接等幾乎每個程序都需要用到的公共配置;
Hei.Private:Private類型,存放當前web應用程序需要使用的連接,比如title,keyword,description;
1542850762853
添加配置
紅圈的地方,有提示Public類型的Namespace能被任何應用讀取
添加完配置記得一定要點擊發布,別問我怎么知道的。。。。
1543283593089
小tips:這些配置可以以文本形式,快速 批量添加的:
1543283919947
五、與Asp.Net Core的親密接觸(使用)
5.1 簡單使用
1、引用nuget包:Com.Ctrip.Framework.Apollo.Configuration
1542852719125
2、添加配置
修改appsetting.json,添加Apollo節點配置:
"apollo": {
"AppId": "myDotnet", //這是我們上面添加的Apollo里面的Appid
"MetaServer": "http://127.0.0.1:8080" //Apollo配置服務器地址,注意這里是8080,不是admin的8070
}
3、修改Program.cs,修改為:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, builder) =>
{
builder
.AddApollo(builder.Build().GetSection("apollo"))
.AddDefault() //默認的application Namespace
.AddNamespace("TEST1.Hei.Public ") //public 類型的Namespace
.AddNamespace("Hei.Private");//private 類型的Namespace
})
.UseStartup
非常簡單,我們總共就修改了這3個地方,用起來也跟獲取本地配置幾乎無差;
1543284034098
來,我們看看運行結果:
Public類型的:
1543284400433
Private類型的:
1543284433973
測試的時候可以隨時在Apollo后台修改配置 發布后,刷新鏈接;可以看到,配置即時起效的。
5.2 高級用法
其實也不是什么高級用法。。。
像什么回滾功能很容易理解;灰度發布,大家也可以試着用一下;
1、關聯類型的Namespace
大家注意,我們之前一直使用的應用都是:myDotnet現在我們再添加一個netcore的應用,並且這個應用有一個Public的Namespace TEST2.Hei.Globa
注意這里的MongoDB 跟上面的 myDotnet的配置的值不一樣了
1543287894670
然后,我們給myDotnet 關聯上這個 netcore的TEST2.Hei.Globa ,就等於myDotnet下面多了一個Namespace:
1543287820353
看到myDotnet下面多了一個Namespace:
1543288136940
修改下Program.cs
1543288281731
然后我們看看配置:
MongoDB:還是以myDotnet的為准。
1543287947865
MysqlVersion:
1543288318925
2、監聽配置的變化
偷懶直接上代碼:
private static void OnChanged(object sender, ConfigChangeEventArgs changeEvent)
{
Console.WriteLine("Changes for namespace {0}", changeEvent.Namespace);
foreach (string key in changeEvent.ChangedKeys)
{
ConfigChange change = changeEvent.GetChange(key);
Console.WriteLine("Change - key: {0}, oldValue: {1}, newValue: {2}, changeType: {3}", change.PropertyName, change.OldValue, change.NewValue, change.ChangeType);
}
}
static void Main(string[] args)
{
Config config = ConfigService.GetAppConfig(); //config instance is singleton for each namespace and is never null
config.ConfigChanged += OnChanged;
while (true)
{
Thread.Sleep(500);
var timeout = config.GetProperty("timeout", "");
Console.WriteLine(timeout);
}
}
總結
這篇文章的目的,是希望能給大家提供兩點參考:Apollo是什么?Apollo可以做什么?
達到這兩點也就差不多了;至於Apollo提供的更多功能大家可以慢慢體會,我也在學習當中。至於Apollo的性能、穩定性這些,Apollo目前已經有不少公司落地使用了,是社區里面非常熱的產品,說這些問題,應該都已解決。最后,我也是學習當中,有寫的不對的地方,大家指正,歡迎交流。
demo源碼地址
[參考]
https://github.com/ctripcorp/apollo/wiki/
https://www.cnblogs.com/edisonchou/p/9419379.html
作者:喬達摩 (嘿~)