詳解apollo的設計與使用

子月生發表於2021-06-22

簡介

apollo 是一款由攜程團隊開發的配置中心,可以實現配置的集中管理、分環境管理、即時生效等等。在這篇部落格中,我們可以瞭解到:

  1. 為什麼使用配置中心
  2. 如何設計一個配置中心
  3. apollo 是如何設計的
  4. 如何使用 apollo

為什麼使用配置中心

這裡我回答的是為什麼使用配置中心,而不是為什麼使用 apollo。為什麼呢?因為我不建議使用 apollo,之所以研究它,只是好奇而已。另外,為什麼使用配置中心,這個是需求層面的問題,需求是明確的,但實現需求的手段就不一定了。這個有點像人需要吃飯但不一定得吃饅頭。

首先,我們可以想象下,如果沒有配置中心,我們的專案可能是這樣的:不同環境的配置檔案都放在專案裡面,部署時可以通過啟動引數來指定使用哪個環境的配置。

zzs_apollo_01

這種方式有兩個比較大的缺點:

  1. 不安全。專案的開發人員可以看到生產環境的各種地址、賬號、密碼等等,這是不安全的;
  2. 配置更新需要重啟專案才能生效。

配置中心就是為了解決這些問題而存在的。

如何設計一個配置中心

安全

還是繼續上面的分析。為了解決配置的安全問題,我們很自然地會想到把配置檔案放到一個開發人員看不到的地方,即專案和配置分離,如圖所示。這個放配置的地方可以是資料庫,可以是遠端檔案,也可以是獨立的應用,等等。

zzs_apollo_02

這樣就能解決安全問題了嗎?還是不行,專案的開發人員還是能看到生產的配置。為什麼呢?因為測試環境和生產環境共用一個配置中心,開發人員能拿到測試環境的配置,也就能拿到生產環境的配置。所以,環境不同,配置中心也不一樣(如果非要共用一個,得想好隔離方案)。

zzs_apollo_03

即時釋出

接著,我們來解決第二個問題:配置的即時釋出。

我們需要在客戶端和配置中心之間建立某種機制,讓客戶端可以感知到配置的變化,一般可以通過以下方式實現(apollo 兩種方式都用了):

  1. 客戶端定時重拉配置;
  2. 服務端主動推送。

還有一點需要注意,客戶端拿到新的配置後,需要讓配置生效,即把新配置注入到對應的類中,這一點在整合了 spring 的專案裡會好處理一些。

那麼 apollo 是如何實現的呢?我們可以關注下com.ctrip.framework.apollo.spring.property.SpringValueRegistry這個類,它裡面存放了專案的所有配置資訊,客戶端感知到配置變更後,只要更新這上面的配置就行。而這個類裡面的配置是通過BeanDefinitionRegistryPostProcessor+BeanFactoryPostProcessor來完成初始化的。原理並不複雜,這裡就不擴充套件了。

方便管理

另外,為了更方便地管理配置,配置中心一般會有控制檯。控制檯有兩種形式(apollo 採用第一種):

  1. 所有環境共用一個控制檯(這種情況需要增加一個應用來整合各個環境的配置);
  2. 不同環境使用不同的控制檯。
zzs_apollo_04

經過以上的分析,我們設計出了一個簡單的配置中心。

apollo是如何設計的

關於這個問題,官方給出了這樣一張圖。

zzs_apollo_05

是不是看不懂呢?其實看不懂很正常,因為作為一個配置中心來說,apollo 太重了

我們還是繼續上面的分析,在雛形的基礎上慢慢設計出 apollo 的結構。

首先,如果配置中心是單獨的應用,配置資訊放在資料庫裡面,它的結構大概是這樣的。

zzs_apollo_06

apollo 將這裡的 config server 拆分成了 config service 和 admin service,前者負責與 app001互動,後者負責與 config console 互動。這一步吧,我倒是覺得可有可無。

zzs_apollo_07

其實分析到這裡,apollo 作為配置中心的部分已經完整的畫出來了。目前為止,apollo 還算是一箇中規中矩的配置中心,但是,apollo 給的東西太多了,它還提供了叢集支援,官方給的圖中,meta server、eureka 都屬於這部分。我認為,叢集的支援本意是好的,但僅僅為了支援這個功能讓 apollo 變得太過龐大。

那麼,要如何實現叢集支援呢?其實有一個最簡單的方案,就是直接通過 SLB 訪問即可。

zzs_apollo_08

但是人家 apollo 偏偏要用 eureka,如圖所示。config service 需要先註冊到 eureka server,然後 app001 要先從 eureka server 獲取 config service 的地址,然後再訪問。config console 和 admin service 的互動同理。

zzs_apollo_09

走到這裡,無非是採用 SLB 還是採用 eureka 來實現負載均衡,還是可以接受的。

但是呢?使用 eureka 來實現負載均衡的話,就要求 app001 必須引入 eureka client,但我不想引入怎麼辦。於是,apollo 開發團隊又搞出一個新的專案 meta server 來遮蔽對 eureka 的依賴。

zzs_apollo_10

我們發現,apollo 已經大得離譜了。

然而還沒完,在上面的結構圖中,我們會發現,meta server 如果掛了,config service 做再多叢集也沒用,也就是說 meta server 也需要做叢集,這時應該怎麼處理呢?apollo 官方給出了方案--使用 SLB。

那麼,我想問,為什麼不一開始就使用 SLB 呢??

我看了官閘道器於這個問題的回答,之所以這麼設計是為了避免客戶端和 config service 之間的長連線給 SLB 增加過多的負擔。當然,這種解釋還是可以接受,但是不是有更好的方案呢?

zzs_apollo_12

如何使用apollo

測試方案

我把 apollo github 上的程式碼拉到本地重新編譯打包,程式碼稍有改動。我的測試方案如下。

伺服器 1 是我的 windows 電腦,用來模擬 dev 環境,上面部署了配置中心、eureka、資料庫,客戶端和 portal 也部署在這臺電腦。

伺服器 2 是我的 linux 伺服器,用來模擬 pro 環境,上面部署了配置中心、eureka、資料庫。

zzs_apollo_11

環境說明

os:伺服器1:win 10,伺服器2:linux

eureka:1.10.11

apollo:1.8.0

maven:3.6.3

jdk:1.8.0_231

mysql:5.7.28

建立資料庫

在伺服器 1 和伺服器 2 新建資料庫ApolloPortalDBApolloConfigDB,具體指令碼為apollo sql

zzs_apollo_13

啟動eureka

config service 中自帶了一個 eureka server,但我不打算用,所以後面的測試中都會將它禁用掉。這裡分別啟動伺服器 1 和伺服器 2 的 eureka,埠為 8080。eureka 相關內容可以參考我的另一篇部落格:Java原始碼詳解系列(十二)--Eureka的使用和原始碼

啟動config service和meta server

mvn clean package打包 config service 專案,通過批處理檔案啟動專案(根據作業系統選擇不同的指令碼),埠是 8081。config service 裡面整合了 meta server,所以,這裡我們同時啟動了 config service 和 meta server。

zzs_apollo_14

啟動admin service

mvn clean package打包 admin service 專案,通過批處理檔案啟動專案,埠是 8082。在我們的測試例子中,config service 和 admin service 誰先啟動都可以,但是,如果我們使用了 config service 裡的 eureka server,那麼必須先啟動 config service。

zzs_apollo_15

啟動portal

mvn clean package打包 portal 專案,通過批處理檔案啟動專案,埠是 8083。

zzs_apollo_16

這個時候,我們可以通過http://127.0.0.1:8083/訪問管理介面(賬號 apollo,密碼 admin)。我們可以看到例項專案 SampleApp,它的兩個環境分別對應我們伺服器 1 和伺服器 2 的配置中心。

zzs_apollo_17

啟動apollo demo

apollo demo 用來模擬我們的實際專案,演示從配置中心獲取配置,專案中需要引入 apollo-client 的依賴。

mvn clean package打包專案,通過批處理檔案啟動專案(連線的是 dev 的配置中心,可以自行修改)。當我們輸入 key 為 timeout 時,可以拿到配置中心的 value 為 100。

zzs_apollo_18

走到這裡,我們成功地完成了 apollo 的部署。

以上基本講完了 apollo 的結構和使用。如有錯誤,歡迎指正。

最後,感謝閱讀。

參考資料

apollo官方文件

相關原始碼請移步:https://github.com/ZhangZiSheng001/apollo-demo

本文為原創文章,轉載請附上原文出處連結:https://www.cnblogs.com/ZhangZiSheng001/p/14918588.html

相關文章