1.概述
1.1定義
Apollo,稱阿波羅,是攜程研發的開源配置管理中心,能夠集中化管理應用不同環境、不同集群的配置,配置修改后能夠實時推送到應用端,並且具備規范的權限、流程治理等特性。它支持4個維度管理Key-Value格式的配置。
1.2特性
1)統一管理不同環境、不同集群的配置
Apollo提供了一個統一界面集中式管理不同環境(environment)、不同集群(cluster)、不同命名空間(namespace)的配置。同一份代碼部署在不同的集群,可以有不同的配置。通過命名空間(namespace)可以很方便的支持多個不同應用共享同一份配置,同時還允許應用對共享的配置進行覆蓋
2)配置修改實時生效(熱發布)
用戶在Apollo修改完配置並發布后,客戶端能實時(1秒)接收到最新的配置,並通知到應用程序
3)版本發布管理
所有的配置發布都有版本概念,從而可以方便地支持配置的回滾
4)灰度發布
點了發布后,只對部分應用實例生效,等觀察一段時間沒問題后再推給所有應用實例
5)權限管理、發布審核、操作審計
應用和配置的管理都有完善的權限管理機制,對配置的管理還分為了編輯和發布兩個環節,從而減少人為的錯誤。另外所有的操作都有審計日志,可以方便的追蹤問題
1.3執行流程
執行流程圖如下:
流程說明:
A:用戶在配置中心發布或修改配置
B:Apollo客戶端定時拉取配置中心的配置。若配置中心發生故障,則apollo客戶端會從本地緩存中獲取配置信息
C:應用程序從客戶端獲取配置信息並更新通知
D:除了apollo客戶端定時從拉取配置中心拉取之外,配置中心還可以實時的推送配置更新信息到apollo客戶端,那么客戶端再把配置給應用程序
2.安裝及部署
可參考官方指南https://github.com/ctripcorp/apollo/wiki/%E5%88%86%E5%B8%83%E5%BC%8F%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97#,本操作均按照指南進行說明的。
2.1環境要求
1)服務端基於Spring Boot框架,一般放在Centos7上
2)JDK版本需在1.8+
3)MySQL版本需在5.6.5+
2.2在Linux手動部署服務端
2.2.1創建數據庫
Apollo服務端共需要兩個數據庫:ApolloPortalDB
和ApolloConfigDB
。ApolloPortalDB只需要在生產環境部署一個即可,而ApolloConfigDB需要在每個環境部署一套。
1)創建ApolloPortalDB數據庫:復制apolloportaldb.sql后執行。
2)創建ApolloConfigDB數據庫:復制apolloconfigdb.sql后執行。
2.2.2下載安裝包
1)直接從GitHub Release下載即可。
這里以1.8.1版本為例,需要分別下載apollo-configservice-1.8.1-github.zip、apollo-adminservice-1.8.1-github.zip和apollo-portal-1.8.1-github.zip。如下圖:
2)修改數據庫配置信息
下載后在本地解壓,然后分別打開三個這文件夾下的config/application-github.properties
文件,修改數據庫的連接信息。下面以一個為例說明:
# DataSource spring.datasource.url = jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8 spring.datasource.username = admin spring.datasource.password = 1234
需要修改數據庫的地址,用戶名和密碼。需要注意的是在用戶名和密碼未部不能有空格!這里的MySQL使用的是8.0+版本的,使用docker容器啟動的,專門創建了一個用戶,用於外部的訪問。
3)修改portal的環境配置
這里以默認的dev環境進行說明,若需要添加其他的環境,可參考后續章節。
打開apollo-portal-1.8.1-github/config/apollo-env.properties
文件,修改dev.meta的值
dev.meta=http://localhost:8080
2.2.3啟動服務
1)把上一步修改好后的三個文件夾全部上傳到虛擬機中。
2)部署apollo-configservice
cd apollo-configservice-1.8.1-github/scripts
./startup.sh
啟動需要幾分鍾,看到下圖的執行結果說明啟動成功!后面的兩個服務類同。
停止服務
./shutdown.sh
3)部署apollo-adminservice
cd apollo-adminservice-1.8.1-github/scripts
./startup.sh
4)部署apollo-portal
cd apollo-portal-1.8.1-github/scripts
./startup.sh
都啟動后訪問http://192.168.86.128:8070/,這里的ip是虛擬機的ip。看到apollo的登錄頁面,說明服務均部署成功。
5)登錄管理頁面
默認的用戶名是apollo,密碼是admin,即可登錄進入首頁,第一次進來可能會提示下圖的錯誤信息,這時需要點擊左下角的補缺環境就可以正常使用了。
正常情況下是下圖:
用戶名和密碼存儲在apolloportaldb數據庫的Users表中,可修改。
2.3在Linux使用Docker部署服務端
Apollo1.7.0及以上的版本才能使用Docker部署,這里以1.8.1版本為例。數據庫在此略,請參考上一小節的創建數據庫操作說明。
2.3.1部署apollo-configservice
1)拉取鏡像
docker pull apolloconfig/apollo-configservice:1.8.1
2)啟動鏡像
首次啟動時需要指定一些參數,后續只需要啟動此容器即可。每行尾部的反斜杠“\”表示換行。
docker run -p 8080:8080 \ -e SPRING_DATASOURCE_URL="jdbc:mysql://192.168.86.128:3306/ApolloConfigDB?characterEncoding=utf8" \ -e SPRING_DATASOURCE_USERNAME=admin -e SPRING_DATASOURCE_PASSWORD=1234 \ -e EUREKA_INSTANCE_IP_ADDRESS=192.168.86.128 -d -v /tmp/logs:/opt/logs --name apollo-configservice apolloconfig/apollo-configservice:1.8.1
參數說明:
SPRING_DATASOURCE_URL: 環境ApolloConfigDB的數據庫地址 SPRING_DATASOURCE_USERNAME: 環境ApolloConfigDB數據庫用戶名 SPRING_DATASOURCE_PASSWORD: 環境ApolloConfigDB數據庫密碼 EUREKA_INSTANCE_IP_ADDRESS:eureka的地址,不能再使用localhost
由於mysql也使用的是docker容器,演示示例中客戶端和服務端不在同一台機器上,故這里數據的連接必須使用ip進行訪問,不能使用localhost,否則服務無法啟動成功。若在正式環境中,服務端和客戶端在同一機器上,那么就不需要設置eureka地址。后續使用docker部署同。
3)修改eureka的地址
由於使用的是容器,故需要把eureka的地址中localhost改為ip:
use ApolloConfigDB; update ServerConfig t set t.Value = 'http://192.168.86.128:8080/eureka/' where t.Key = 'eureka.service.url'
這里不改的話,config服務啟動時會報異常。
12.3.2部署apollo-adminservice
1)拉取鏡像
docker pull apolloconfig/apollo-adminservice:1.8.1
2)啟動鏡像
首次啟動時需要指定一些參數,后續只需要啟動此容器即可。每行尾部的反斜杠“\”表示換行。
docker run -p 8090:8090 \ -e SPRING_DATASOURCE_URL="jdbc:mysql://192.168.86.128:3306/ApolloConfigDB?characterEncoding=utf8" \ -e SPRING_DATASOURCE_USERNAME=admin -e SPRING_DATASOURCE_PASSWORD=1234 \ -d -v /tmp/logs:/opt/logs --name apollo-adminservice apolloconfig/apollo-adminservice:1.8.1
參數說明:
SPRING_DATASOURCE_URL: 環境ApolloConfigDB的數據庫地址 SPRING_DATASOURCE_USERNAME: 環境ApolloConfigDB數據庫用戶名 SPRING_DATASOURCE_PASSWORD: 環境ApolloConfigDB數據庫密碼
2.3.3部署apollo-portal
1)拉取鏡像
docker pull apolloconfig/apollo-portal:1.8.1
2)啟動鏡像
首次啟動時需要指定一些參數,后續只需要啟動此容器即可。每行尾部的反斜杠“\”表示換行。
docker run -p 8070:8070 \ -e SPRING_DATASOURCE_URL="jdbc:mysql://192.168.86.128:3306/ApolloPortalDB?characterEncoding=utf8" \ -e SPRING_DATASOURCE_USERNAME=admin -e SPRING_DATASOURCE_PASSWORD=1234\ -e APOLLO_PORTAL_ENVS=dev \ -e DEV_META=http://192.168.86.128:8080 \ -d -v /tmp/logs:/opt/logs --name apollo-portal apolloconfig/apollo-portal:1.8.1
參數說明:
SPRING_DATASOURCE_URL: 環境ApolloPortalDB數據庫地址 SPRING_DATASOURCE_USERNAME: 環境ApolloPortalDB數據庫用戶名 SPRING_DATASOURCE_PASSWORD: 環境ApolloPortalDB數據庫密碼 APOLLO_PORTAL_ENVS(可選): 對應ApolloPortalDB中的apollo.portal.envs配置項,如果沒有在數據庫中配置的話,可以通過此環境參數配置 DEV_META/PRO_META(可選): 配置對應環境的Meta Service地址,以${ENV}_META命名,需要注意的是如果配置了ApolloPortalDB中的apollo.portal.meta.servers配置,則以apollo.portal.meta.servers中的配置為准
這里只配置了dev環境。若配置多環境,啟動時再添加參數即可,下列代碼標紅的地方便是添加pro后的樣子:
docker run -p 8070:8070 \ -e SPRING_DATASOURCE_URL="jdbc:mysql://192.168.86.128:3306/ApolloPortalDB?characterEncoding=utf8" \ -e SPRING_DATASOURCE_USERNAME=admin -e SPRING_DATASOURCE_PASSWORD=1234\ -e APOLLO_PORTAL_ENVS=dev,pro \ -e DEV_META=http://localhost:8080 -e PRO_META=http://ip:8080 \ -d -v /tmp/logs:/opt/logs --name apollo-portal apolloconfig/apollo-portal:1.8.1
2.4在Linux使用Docker-Compose部署服務端
在上一小節使用的docker命令方式部署服務端,本小節使用Docker-Compose進行部署,故默認已安裝docker-compose鏡像,若未安裝,請參考https://www.cnblogs.com/zys2019/p/13292619.html#_label4。
1)數據庫請參數2.2小節的創建數據庫操作。
2)修改數據庫中eureka的地址
use ApolloConfigDB; update ServerConfig t set t.Value = 'http://192.168.86.128:8080/eureka/' where t.Key = 'eureka.service.url'
3)在opt目錄下新建apollo目錄,在apollo目錄新建.env文件,內容如下:
DATASOURCE_URL_CONFIG=jdbc:mysql://192.168.86.128:3306/ApolloConfigDB?characterEncoding=utf8 DATASOURCE_URL_PORTAL=jdbc:mysql://192.168.86.128:3306/ApolloPortalDB?characterEncoding=utf8 DATASOURCE_USERNAME=admin DATASOURCE_PASSWORD=1234 APOLLO_PORTAL_ENVS=dev DEV_META=http://192.168.86.128:8080 EUREKA_INSTANCE_IP_ADDRESS=192.168.86.128
此文件的作用是定義公共的變量,在docker-compose.yml中直接獲取即可。
4)在apollo目錄下新建docker-compose.yml文件,內容如下:
version: '3.7' services: apollo-configservice: container_name: apollo-configservice restart: always image: apolloconfig/apollo-configservice:1.8.1 ports: - 8080:8080 environment: SPRING_DATASOURCE_URL: ${DATASOURCE_URL_CONFIG} SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME} SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD} EUREKA_INSTANCE_IP_ADDRESS: ${EUREKA_INSTANCE_IP_ADDRESS} volumes: - /tmp/logs:/opt/logs apollo-adminservice: container_name: apollo-adminservice depends_on: - apollo-configservice restart: always image: apolloconfig/apollo-adminservice:1.8.1 expose: - '8090' environment: SPRING_DATASOURCE_URL: ${DATASOURCE_URL_CONFIG} SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME} SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD} volumes: - /tmp/logs:/opt/logs apollo-portal: container_name: apollo-portal depends_on: - apollo-adminservice restart: always image: apolloconfig/apollo-portal:1.8.1 ports: - 8070:8070 environment: SPRING_DATASOURCE_URL: ${DATASOURCE_URL_PORTAL} SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME} SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD} APOLLO_PORTAL_ENVS: ${APOLLO_PORTAL_ENVS} DEV_META: ${DEV_META} volumes: - /tmp/logs:/opt/logs
完成后在當前位置啟動docker-compose即可,命令是:
docker-compose up -d
2.5在配置中心配置相關信息
服務端部署完成后,訪問http://192.168.86.128:8070並登錄進入首頁。下面的操作均以進入首頁后說明。
1)創建項目
點擊首頁的創建項目,填寫項目的相關信息
部門:選擇應用所在的部門 應用AppId:用來標識應用身份的唯一id,格式為string 應用名稱:應用名,僅用於界面展示。 應用負責人:選擇的人默認會成為該項目的管理員,具備項目權限管理、集群創建、Namespace創建等權限。
2)添加配置項
點擊頁面的新增配置按鈕,配置需要管理的 application.properties 中的屬性,這是第一步。
在彈框中輸入key和value,這里以count=20為例,點擊提交
提交后在頁面會顯示出來
3)發布配置
選擇發布按鈕,發布配置,這是第二步。在發布的彈框中選擇發布按鈕即可
發布后界面就會顯示已發布
3.apollo客戶端的安裝
經過配置中心的配置,就可以使用SpringBoot來整合apollo了。源碼:https://github.com/zhongyushi-git/springboot-apollo-demo.git
1)新建一個SpringBoot的項目。新建時選擇web的依賴
2)導入apollo的依賴
<dependency> <groupId>com.ctrip.framework.apollo</groupId> <artifactId>apollo-client</artifactId> <version>1.3.0</version> </dependency>
3)在配置文件application.properties配置apollo的相關信息
#阿波羅配置 app.id = apollo-application apollo.meta=http://192.168.86.128:8080 apollo.bootstrap.enabled = true apollo.bootstrap.eagerLoad.enabled=true
說明:
app.id:AppId是應用的身份信息,是配置中心獲取配置的一個重要信息。這個必須和配置中心保持一致 apollo.meta:指定config服務地址 apollo.bootstrap.enabled:在應用啟動階段,向Spring容器注入被托管的application.properties文件的配置信息。 apollo.bootstrap.eagerLoad.enabled:將Apollo配置加載提到初始化日志系統之前。
4)在啟動類上添加注解@EnableApolloConfig
5)編寫一個controller接口,讀取配置文件的信息
package com.zxh.springbootapollodemo.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/test") public class TestController { @Value("${count}") private Integer count; @GetMapping("/get") public String test() { return "count的值:" + count; } }
6)啟動項目,訪問http://localhost:8080/test/get,返回正確的信息
7)在配置中心修改count的值,將其改為666並發布
8)看到控制台打印了日志,更新了配置的信息,再訪問get接口,返回的也是最新的值
當然有時無法及時的更新,可能是網絡原因,也可能是時間問題,發布后等待一分鍾再進行測試。
4.使用Docker-Compose部署多環境
上述講的都是單個環境,一般情況下會部署多環境,下面在同一台linux機器上部署dev和pro環境。
4.1創建數據庫
參考2.2小節的創建數據庫操作,分別創建如下圖數據庫:
其中ApolloPortalDB只需要創建一個,而ApolloConfigDB需要對每個環境單獨創建一個。創建完成后修改eureka的服務地址:
use ApolloConfigDB_DEV; update ServerConfig t set t.Value = 'http://192.168.86.128:8080/eureka/' where t.Key = 'eureka.service.url'; use ApolloConfigDB_PRO; update ServerConfig t set t.Value = 'http://192.168.86.128:8081/eureka/' where t.Key = 'eureka.service.url';
4.2創建.env文件
在/opt目錄下新建目錄,名字為apollo_profile,在apollo_profile目錄下新建.env文件,內容如下:
DATASOURCE_URL_CONFIG_DEV=jdbc:mysql://192.168.86.128:3306/ApolloConfigDB_DEV?characterEncoding=utf8 DATASOURCE_URL_CONFIG_PRO=jdbc:mysql://192.168.86.128:3306/ApolloConfigDB_PRO?characterEncoding=utf8 DATASOURCE_URL_PORTAL=jdbc:mysql://192.168.86.128:3306/ApolloPortalDB?characterEncoding=utf8 DATASOURCE_USERNAME=admin DATASOURCE_PASSWORD=1234 APOLLO_PORTAL_ENVS=dev,pro DEV_META=http://192.168.86.128:8080 PRO_META=http://192.168.86.128:8081 EUREKA_INSTANCE_IP_ADDRESS=192.168.86.128
這里面設置了一些公共的變量,方便維護。
4.3創建docker-compose.yml文件
在apollo_profile目錄下新建docker-compose.yml文件,內容如下:
version: '3.7' services: apollo-configservice-dev: container_name: apollo-configservice-dev restart: always image: apolloconfig/apollo-configservice:1.8.1 ports: - 8080:8080 environment: SPRING_DATASOURCE_URL: ${DATASOURCE_URL_CONFIG_DEV} SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME} SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD} EUREKA_INSTANCE_IP_ADDRESS: ${EUREKA_INSTANCE_IP_ADDRESS} volumes: - /tmp/logs:/opt/logs apollo-adminservice-dev: container_name: apollo-adminservice-dev depends_on: - apollo-configservice-dev restart: always image: apolloconfig/apollo-adminservice:1.8.1 expose: - '8090' environment: SPRING_DATASOURCE_URL: ${DATASOURCE_URL_CONFIG_DEV} SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME} SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD} volumes: - /tmp/logs:/opt/logs apollo-configservice-pro: container_name: apollo-configservice-pro restart: always image: apolloconfig/apollo-configservice:1.8.1 ports: - 8081:8081 environment: #修改容器啟動的端口號 SERVER_PORT: '8081' SPRING_DATASOURCE_URL: ${DATASOURCE_URL_CONFIG_PRO} SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME} SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD} EUREKA_INSTANCE_IP_ADDRESS: ${EUREKA_INSTANCE_IP_ADDRESS} volumes: - /tmp/logs:/opt/logs apollo-adminservice-pro: container_name: apollo-adminservice-pro depends_on: - apollo-configservice-pro restart: always image: apolloconfig/apollo-adminservice:1.8.1 expose: - '8090' environment: SPRING_DATASOURCE_URL: ${DATASOURCE_URL_CONFIG_PRO} SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME} SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD} volumes: - /tmp/logs:/opt/logs apollo-portal: container_name: apollo-portal depends_on: - apollo-adminservice-dev - apollo-adminservice-pro restart: always image: apolloconfig/apollo-portal:1.8.1 ports: - 8070:8070 environment: SPRING_DATASOURCE_URL: ${DATASOURCE_URL_PORTAL} SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME} SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD} APOLLO_PORTAL_ENVS: ${APOLLO_PORTAL_ENVS} DEV_META: ${DEV_META} PRO_META: ${PRO_META} volumes: - /tmp/logs:/opt/logs
在上述的配置中,config和admin容器需要為每個環境單獨配置,故有兩個;而所有環境共用一個portal容器。這兩個配置文件在源代碼的資源目錄下保存了一份供參考。
需要注意的是,config容器的默認端口是8080,由於在同一台機器上,需要修改其啟動的端口,從而注冊到Eureka中。這點很重要,對於多台機器,每台部署一個環境時,可不用修改。
4.4啟動容器
啟動命令:
docker-compose up -d
啟動可能比較慢,待所有容器完全啟動成功后,訪問http://192.168.86.128:8070並登錄。然后創建一個項目(請參考上一章節的說明,app.id等信息保持不變),如下圖:
可以看到,在左側的環境列表中,顯示了配置的所有的環境。需要給每個環境新增配置並發布。
4.5測試
還是以上面的代碼為例進行說明:
1)測試dev環境
在上面的配置中,dev環境對應的config的端口是8080,故把配置文件的url改成:
apollo.meta=http://192.168.86.128:8080
然后啟動項目,訪問http://localhost:8080/test/get,獲取的是dev環境的值
2)測試pro環境
在上面的配置中,pro環境對應的config的端口是8081,故把配置文件的url改成:
apollo.meta=http://192.168.86.128:8081
然后啟動項目,訪問http://localhost:8080/test/get,獲取的是pro環境的值