Apollo配置中心

Apollo介紹

Apollo(阿波羅)是攜程框架部門研發(fā)的開源配置管理中心,能夠集中化管理應用不同環(huán)境、不同集群的配置,配置修改后能夠實時推送到應用端,并且具備規(guī)范的權限、流程治理等特性。

Apollo支持4個維度管理Key-Value格式的配置:

  1. application (應用)
  2. environment (環(huán)境)
  3. cluster (集群)
  4. 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和Spring Cloud Config的區(qū)別.png

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安裝包

2. 安裝步驟

2.1 創(chuàng)建數(shù)據(jù)庫

Apollo服務端共需要兩個數(shù)據(jù)庫:ApolloPortalDBApolloConfigDB,數(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

具體使用指南可參考官網

該服務端只是用來初步體驗和測試使用。

Apollo的客戶端

Apollo支持基于Spring Boot、基于Java、基于XML等等多種方式的配置,具體詳情可參考官網

Apollo會在本地存一份緩存配置文件

  • Mac/Linux上文件位置為/opt/data/{appId}/config-cache
  • Windows上文件位置為C:\opt\data{appId}\config-cache
  • 本地配置文件會以{appId}+{cluster}+{namespace}.properties的文件名和格式存儲,當獲取不到網絡配置時會從這個配置中取值

下面我就介紹最常用、簡便、快捷、通用的方式,即基于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客戶端的使用

  1. 通過@Value注解即可獲取到值

  2. 可以以類的方式作為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;
         }
     }
    
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容