Apollo 是一款可靠的分布式配置管理中心,誕生于攜程框架研發(fā)部,能夠集中化管理應(yīng)用不同環(huán)境、不同集群的配置,配置修改后能夠?qū)崟r(shí)推送到應(yīng)用端,并且具備規(guī)范的權(quán)限、流程治理等特性,適用于微服務(wù)配置管理場景。
產(chǎn)品特色
- 分布式配置管理:在微服務(wù)架構(gòu)中,應(yīng)用程序可能分為多個微服務(wù)組件。Apollo可以幫助開發(fā)者集中管理這些微服務(wù)的配置信息,實(shí)現(xiàn)配置的統(tǒng)一化和集中化。
- 動態(tài)配置更新:Apollo支持在線修改配置并實(shí)時(shí)推送到各個客戶端,無需重新部署應(yīng)用程序。這有助于提高系統(tǒng)的靈活性和可維護(hù)性。
- 多環(huán)境和多集群配置支持:Apollo允許在不同環(huán)境(如開發(fā)、測試、生產(chǎn)等)和不同集群下管理配置信息。這有助于開發(fā)者在不同場景下靈活地使用和管理配置。
- 灰度發(fā)布:Apollo支持配置的灰度發(fā)布,允許開發(fā)者逐步推出新的配置更改,以便更好地控制風(fēng)險(xiǎn)和觀察配置更改的影響。
- 權(quán)限管理和審計(jì):Apollo提供了完善的權(quán)限管理和操作審計(jì)功能,有助于保證配置信息的安全和準(zhǔn)確。
- 高可用性和容錯性:Apollo采用分布式部署,確保了系統(tǒng)的高可用性和容錯性。
貼上一張官方的結(jié)構(gòu)圖
image.png
這張圖現(xiàn)在看,疑惑是正常的,那么就接著文章繼續(xù)往下看
主要模塊解析
- Portal Service 前端web管理界面,提供可視化的配置管理界面,支持配置的添加、修改、刪除等操作,并能夠?qū)ε渲眠M(jìn)行版本控制和歷史回滾,通過IP+Port訪問服務(wù)
- Config Service 提供配置的讀取、推送等功能,提供配置更新推送接口(基于Http long polling),服務(wù)對象是Apollo客戶端
對于負(fù)載是否會大的設(shè)計(jì)
- 服務(wù)端使用Spring DeferredResult實(shí)現(xiàn)異步化,從而大大增加長連接數(shù)量
- 目前使用的tomcat embed默認(rèn)配置是最多10000個連接(可以調(diào)整),使用了4C8G的虛擬機(jī)實(shí)測可以支撐10000個連接,所以滿足需求(一個應(yīng)用實(shí)例只會發(fā)起一個長連接)
- Admin Service 提供配置的修改、發(fā)布等功能,服務(wù)對象是 Portal(管理界面)
- Eureka 項(xiàng)目依賴于微服務(wù),Config Service和Admin Service會向Eureka注冊服務(wù),并保持心跳,目前Eureka在部署時(shí)和Config Service是在一個JVM進(jìn)程中的
- Client 業(yè)務(wù)代碼客戶端拉取配置,通過IP+Port訪問服務(wù)
部署
環(huán)境依賴: java1.8+,Centos7(windows可選擇Quick Start方式體驗(yàn)),mysql5.6.5+
本文將分部署部署2個節(jié)點(diǎn),從而體驗(yàn)2個環(huán)境的應(yīng)用,我們通過不同端口的方法,來模擬2個linux服務(wù)器,為此準(zhǔn)備了
10.0.50.20 linux服務(wù)器,運(yùn)行Apollo服務(wù)
10.0.54.9 mysql服務(wù)器
10.0.50.65 mysql服務(wù)器
創(chuàng)建數(shù)據(jù)庫
Apollo服務(wù)端共需要兩個數(shù)據(jù)庫:ApolloPortalDB和ApolloConfigDB,我們把數(shù)據(jù)庫、表的創(chuàng)建和樣例數(shù)據(jù)都分別準(zhǔn)備了sql文件,只需要導(dǎo)入數(shù)據(jù)庫即可。
ApolloPortalDB 大多提供了
Portal Server管理界面的配置,里面繼承了多維度(例如環(huán)境、節(jié)點(diǎn)配置)的管理,所以只需要在生產(chǎn)環(huán)境部署一個即可
1.1 10.0.54.9創(chuàng)建ApolloPortalDB數(shù)據(jù)庫
1.2 導(dǎo)入數(shù)據(jù)https://github.com/apolloconfig/apollo/blob/master/scripts/sql/apolloportaldb.sqlApolloConfigDB 需要在每個環(huán)境部署一套,如dev、uat和pro分別部署3套ApolloConfigDB,屬于各個節(jié)點(diǎn)的業(yè)務(wù)存儲
2.1 10.0.54.9和10.0.50.65分別創(chuàng)建ApolloConfigDB數(shù)據(jù)庫
2.2 分別導(dǎo)入數(shù)據(jù)https://github.com/apolloconfig/apollo/blob/master/scripts/sql/apolloconfigdb.sql
下載安裝包
本文演示 Apollo 2.0.1 版本
地址 https://github.com/apolloconfig/apollo/releases,Assets模塊有java源碼及打包好的jar兩種類型的鏈接,這里我們下載打包好的安裝包來省去我們本地編譯過程
下載三個安裝包到 10.0.50.20 服務(wù)器
apollo-adminservice-2.0.1-github.zip、apollo-configservice-2.0.1-github.zip、apollo-portal-2.0.1-github.zip
部署配置安裝包
10.0.50.20 服務(wù)器,/home/www/configCenter目錄下新建5個文件夾 admin、admin_2、config、config_2、portal
- 文件夾 admin,節(jié)點(diǎn)1的 Admin Server服務(wù)
- 拷貝
apollo-adminservice-2.0.1-github.zip包到此目錄下,并解壓 - 修改
config/application-github.properties文件,此為節(jié)點(diǎn)1 Admin Server的ApolloConfigDB數(shù)據(jù)庫句柄
# DataSource
spring.datasource.url = jdbc:mysql://10.0.54.9:3306/ApolloConfigDB?characterEncoding=utf8
spring.datasource.username = saas_php
spring.datasource.password = 123QWEasd!@#
- 修改
scripts/startup.sh文件(此項(xiàng)為Admin Server監(jiān)聽端口,此步暫不修改)
SERVER_PORT=${SERVER_PORT:=8090}
- 文件夾 config,節(jié)點(diǎn)1的 Config Server服務(wù)
- 拷貝
apollo-configservice-2.1.0-github.zip包到此目錄下,并解壓 - 修改
config/application-github.properties文件,此為節(jié)點(diǎn)1 Config Server的ApolloConfigDB數(shù)據(jù)庫句柄
# DataSource
spring.datasource.url = jdbc:mysql://10.0.54.9:3306/ApolloConfigDB?characterEncoding=utf8
spring.datasource.username = saas_php
spring.datasource.password = 123QWEasd!@#
- 修改
scripts/startup.sh文件(此項(xiàng)為Config Server監(jiān)聽端口)
SERVER_PORT=${SERVER_PORT:=8086}
由于Apollo是基于eureka的微服務(wù),另外apollo-configservice同時(shí)承擔(dān)meta server職責(zé),如果要修改端口,注意要同時(shí)ApolloConfigDB.ServerConfig表中的eureka.service.url配置項(xiàng)以及apollo-portal和apollo-client中的使用到的meta server信息
數(shù)據(jù)庫10.0.54.9--ApolloConfigDb.ServerConfig表eureka.service.url值修改為http://localhost:8086/eureka/
meta server信息可在隨后的portal后臺,頁面中配置

- 文件夾 admin_2,節(jié)點(diǎn)2的 Admin Server服務(wù)
- 拷貝
apollo-adminservice-2.0.1-github.zip包到此目錄下,并解壓 - 修改
config/application-github.properties文件,此為節(jié)點(diǎn)2 Admin Server的ApolloConfigDB數(shù)據(jù)庫句柄
# DataSource
spring.datasource.url = jdbc:mysql://10.0.50.65:3306/ApolloConfigDB?characterEncoding=utf8
spring.datasource.username = root
spring.datasource.password = 123456
- 修改
scripts/startup.sh文件(此項(xiàng)為Admin Server監(jiān)聽端口,此步暫不修改)
SERVER_PORT=${SERVER_PORT:=8088}
- 文件夾 config_2,節(jié)點(diǎn)2的 Config Server服務(wù)
- 拷貝
apollo-configservice-2.1.0-github.zip包到此目錄下,并解壓 - 修改
config/application-github.properties文件,此為節(jié)點(diǎn)2 Config Server的ApolloConfigDB數(shù)據(jù)庫句柄
# DataSource
spring.datasource.url = jdbc:mysql://10.0.50.65:3306/ApolloConfigDB?characterEncoding=utf8
spring.datasource.username = root
spring.datasource.password = 123456
- 修改
scripts/startup.sh文件(此項(xiàng)為Config Server監(jiān)聽端口)
SERVER_PORT=${SERVER_PORT:=8087}
此次也與節(jié)點(diǎn)1的 Config Server一樣,需修改兩個參數(shù)
數(shù)據(jù)庫10.0.50.65--ApolloConfigDb.ServerConfig表eureka.service.url值修改為http://localhost:8087/eureka/
meta server信息可在隨后的portal后臺,頁面中配置
- 文件夾 portal,portal Server服務(wù)
- 拷貝
apollo-portal-2.1.0-github.zip包到此目錄下,并解壓 - 修改
config/application-github.properties文件,此為 Portal Server 的ApolloPortalDB數(shù)據(jù)庫句柄
# DataSource
spring.datasource.url = jdbc:mysql://10.0.54.9:3306/ApolloPortalDB?characterEncoding=utf8
spring.datasource.username = saas_php
spring.datasource.password = 123QWEasd!@#
- 本文演示dev fat兩個環(huán)境,修改
config/apollo-env.properties文件
dev.meta=http://10.0.50.20:8086
fat.meta=http://10.0.50.20:8087
這里你會發(fā)現(xiàn),此次的兩個地址,正是我們上文中,節(jié)點(diǎn)1和節(jié)點(diǎn)2的 Config Server地址,此次配置這個原因?yàn)槿缦?br>
3.1 Apollo Portal需要在不同的環(huán)境訪問不同的meta service(apollo-configservice)地址,所以我們需要在配置中提供這些信息
3.2 默認(rèn)情況下,meta service和Config Service是部署在同一個JVM進(jìn)程,所以meta service的地址就是Config Service的地址。
好了,到此處,我們已經(jīng)將準(zhǔn)備工作全部就緒,接下來就是啟動環(huán)節(jié)了,不急,我們再來整理一下
文件夾admin,存放節(jié)點(diǎn)1的Admin Server服務(wù),監(jiān)聽端口8090
文件夾config,存放節(jié)點(diǎn)1的Config Server服務(wù),監(jiān)聽端口8086
文件夾admin_2,存放節(jié)點(diǎn)2的Admin Server服務(wù),監(jiān)聽端口8088
文件夾config_2,存放節(jié)點(diǎn)2的Config Server服務(wù),監(jiān)聽端口8087
文件夾portal,存放全部節(jié)點(diǎn)的Portal Server服務(wù),監(jiān)聽端口8070(scripts/startup.sh我們沒有修改默認(rèn)端口)
而節(jié)點(diǎn)1、2的eureka服務(wù)就是
http://10.0.50.20:8086/
http://10.0.50.20:8087/
是不是感覺多節(jié)點(diǎn)eureka服務(wù)是不是沒必要各自啟動,是的,但不在我們本文介紹中
此處,再來介紹一組概念,以Meta Server為引子
- Portal通過域名訪問Meta Server獲取Admin Service服務(wù)列表(IP+Port)
- Client通過域名訪問Meta Server獲取Config Service服務(wù)列表(IP+Port)
- Meta Server從Eureka獲取Config Service和Admin Service的服務(wù)信息,相當(dāng)于是一個Eureka Client
- 增設(shè)一個Meta Server的角色主要是為了封裝服務(wù)發(fā)現(xiàn)的細(xì)節(jié),對Portal和Client而言,永遠(yuǎn)通過一個Http接口獲取Admin Service和Config Service的服務(wù)信息,而不需要關(guān)心背后實(shí)際的服務(wù)注冊和發(fā)現(xiàn)組件
- Meta Server只是一個邏輯角色,在部署時(shí)和Config Service是在一個JVM進(jìn)程中的,所以IP、端口和Config Service一致
啟動服務(wù)
馬上就要開啟服務(wù)了,我相信看完此小結(jié),就能理解上面的官方設(shè)計(jì)圖了
- 啟動節(jié)點(diǎn)1 Config Server服務(wù)
cd config/scripts/
./startup.sh
- 啟動節(jié)點(diǎn)1 Admin Server服務(wù)
cd admin/scripts/
./startup.sh
- 啟動節(jié)點(diǎn)2 Config Server服務(wù)
cd config_2/scripts/
./startup.sh
- 啟動節(jié)點(diǎn)2 Admin Server服務(wù)
cd admin_2/scripts/
./startup.sh
- 啟動portal Server服務(wù)
cd portal/scripts/
./startup.sh
現(xiàn)在,你可以打開瀏覽器輸入http://10.0.50.20:8070/操作了
開始使用
還記得我們部署那步,讓配置apollo.portal.meta.servers的步驟不,首頁-管理員工具-系統(tǒng)參數(shù)-PortalDb配置
apollo.portal.meta.servers的值修改為{"DEV":"http://10.0.50.20:8086","FAT":"http://10.0.50.20:8087"},配置更新后,一分鐘后自動生效,如果你不信任,可以選擇portal/script目錄下,兩個shell腳本進(jìn)行關(guān)閉、重啟
環(huán)境顯示為我們上面配置的dev和fat環(huán)境的ConfigServer服務(wù)配置項(xiàng)

我們創(chuàng)建兩個應(yīng)用蒼龍一號 蒼龍二號
需要注意的是,
首頁-管理員工具-系統(tǒng)參數(shù)-PortalDb配置中有很豐富的配置項(xiàng),比如部門、用戶限制、key值大小長短等

以蒼龍二號為例

注 application 為 namespaces,必填項(xiàng),默認(rèn)會創(chuàng)建名為application的空間
這里我們創(chuàng)建了一個配置參數(shù)token,左側(cè)有dev和fat兩個參數(shù),客戶端請求時(shí)
dev環(huán)境對應(yīng)的地址為 10.0.50.20:8086
fat環(huán)境對應(yīng)的地址為 10.0.50.20:8087
php客戶端演示示例
composer require multilinguals/apollo-client
<?php
use Org\Multilinguals\Apollo\Client\ApolloClient;
function Handle() {
$server = '10.0.50.20:8087';
$appid = 13162568081;
$namespaces = ['application'];
$apollo = new ApolloClient($server, $appid, $namespaces);
if ($clientIp = getenv('CLIENTIP')) {
$apollo->setClientIp($clientIp);
}
ini_set('memory_limit','128M');
$pid = getmypid();
echo "start [$pid]\n";
$restart = true;
do {
$error = $apollo->start();
if ($error) {
echo('error:'.$error."\n");
sleep(1);
}
}while($error && $restart);
}
代碼目錄下會生成apolloConfig.application.php文件,并持續(xù)監(jiān)聽Apollo Portal 后臺發(fā)布的配置
golang客戶端演示示例
package main
import (
"fmt"
"github.com/shima-park/agollo"
)
func main() {
a, err := agollo.New("http://10.0.50.20:8087", "13162568081", agollo.PreloadNamespaces("application", "test.json"))
if err != nil {
panic(err)
}
errorCh := a.Start() // Start后會啟動goroutine監(jiān)聽變化,并更新agollo對象內(nèi)的配置cache
// 或者忽略錯誤處理直接 a.Start()
watchCh := a.Watch()
for {
select {
case errch := <-errorCh:
// handle error
panic(errch)
case resp := <-watchCh:
fmt.Println(
"Namespace:", resp.Namespace,
"OldValue:", resp.OldValue,
"NewValue:", resp.NewValue,
"Error:", resp.Error,
)
}
}
}
代碼目錄下會生成.agollo文件,并持續(xù)監(jiān)聽Apollo Portal 后臺發(fā)布的配置
現(xiàn)在,我們再拿上一張官網(wǎng)的圖,作為消化

謝謝你看完這篇文章,附上彩蛋一枚
競品 http://www.itdecent.cn/p/50cf94bcb5bb
體驗(yàn)地址 http://console.nacos.io/nacos/index.html
