[享學Archaius] 一、初識Archaius的簡單使用及高級使用

代碼寫越少,bug越少;不寫代碼,纔不會出bug

–> 返回Netflix OSS套件專欄彙總 <–
代碼下載地址:https://github.com/f641385712/netflix-learning

前言

各位小夥伴大家好,我是A哥。從本系列開始,我們將一起進入Netflix Archaius的學習。Netflix Archaius是一個配置管理庫,其重點是來自多個配置存儲的動態屬性。它包括一組用於Netflix的Java配置管理API。它主要實現爲Apache Commons Configuration庫的擴展。提供的主要功能有:

  1. 動態、類型屬性
  2. 高吞吐量和線程安全的配置操作
  3. 一個輪詢框架,允許用戶獲取對配置源的屬性更改
  4. JMX支持
  5. 對於願意使用基於約定的屬性文件位置的應用程序(以及大多數web應用程序),提供開箱即用的複合配置(這是強大功能之一),對於符合配置官網給了一副示例圖如下:

在這裏插入圖片描述


版本約定

本系列所有內容均是基於Archaius1.x進行講解的(確切的說應該是0.x),並且使用的版本約定爲0.7.7

<dependency>
    <groupId>com.netflix.archaius</groupId>
    <artifactId>archaius-core</artifactId>
    <version>0.7.7</version>
</dependency>

爲何選擇已經停更的1.x版本?

這個問題相信任何人都會有疑問,作爲最新教程爲毛不講解最新版本而依舊使用老版本呢?這主要是從實用角度考慮的,原因列出如下:

  1. 相信直接使用Archaius,甚至是直接使用Netflix OSS組件的都極少,一般都是依託於Spring Cloud纔會去使用,因此這纔是主流
  2. 既然有主流我們也應該偏向於主流。截止目前,即使到了Spring Cloud的2.2.1.RELEASE版本,依賴的依舊是Archaius0.7.6版本。所以站在實用的角度,講解老版本才更具實際意義
    1. 此版本對應的SB版本是: 2.2.2.RELEASE;SC版本是:Hoxton.SR1。發佈時間是Nov, 2019,非常新了吧
      在這裏插入圖片描述
  3. 需要說明的是:0.77和0.76版本近乎無差異,可同等看待。而0.77作爲1.x的final最後一版本,因此我就定它嘍

正文

Archaius核心是可以容納一個或多個配置的複合配置的概念。每個配置都可以從諸如JDBC、REST接口、xxx.properties文件等配置源中獲取。可以選擇在運行時對配置源進行輪詢以進行動態更改(在上圖中,爲持久化數據庫配置源;在表中包含屬性的RDBMS,每隔一段時間就會被輪詢一次以進行更改)。

屬性的最終值取決於包含該屬性的最頂層配置(因爲是複合配置)。即,如果一個屬性存在於多個配置中,則應用程序看到的實際值將是配置層次結構中最頂層插槽中的值,當然這種層次結構是可以配置的。


基本使用

使用本地文件作爲配置源

通過使用本地配置文件嚮應用程序提供動態屬性,有兩種方法可以使Archaius開箱即用:

  • 默認情況下,Archaius將在應用程序的類路徑中查找名爲config.properties的文件,並讀取其內容作爲配置屬性。該文件也可以位於jar文件的根目錄中
    • 配置文件名必須叫config.properties才能被自動識別讀取哦,約定大於配置
  • 除了約定值,您可以定義系統屬性archaius.configurationSource.additionalUrls來指定你的文件所在位置,其中包含本地配置文件的URL路徑。例如,將此添加到您的應用程序增加啓動參數:
-Darchaius.configurationSource.additionalUrls=file:///apps/myapp/application.properties

代碼示例
@Test
public void fun1() throws InterruptedException {
    DynamicIntProperty myAge = DynamicPropertyFactory.getInstance().getIntProperty("my.age", 18);
    System.out.println(myAge);
    System.out.println(myAge.get());

    TimeUnit.SECONDS.sleep(80);
    System.out.println("動態修改後的值爲:");
    System.out.println(myAge);
    System.out.println(myAge.get());
}

在classpath下新建一個配置文件,命名爲config.properties

my.name = YoutBatman
my.age = 22

運行程序,在輸出第一句時立馬改動配置文件內容爲(務必記得重新編譯,否則沒有效果):

my.name = YoutBatman
my.age = 100

最後控制檯輸出爲:

DynamicProperty: {name=my.age, current value=22}
22
動態修改後的值爲:
DynamicProperty: {name=my.age, current value=100}
100

上面的代碼中有幾點需要注意:

  • my.age是綁定到long值的屬性。無需任何代碼即可將字符串解析爲long(無需你自己手動強轉嘍)
  • 你的配置文件config.propertiesArchaius自動識別了,自動完成綁定
  • 若你需要動態改變某個key的值,只需編輯配置文件並更改屬性的值即可。默認情況下,Archaius將每分鐘讀取一次文件,並且此更改將在一分鐘之內在您的應用程序中生效
    • 提示:如果你的config.properties是打包在工程內的話,必須重新編譯。如果是外部化配置,則無需操作(報錯落盤了即可)

使用多個URL作爲配置源

除了類路徑上的默認config.properties文件之外,您還可以爲系統屬性archaius.configurationSource.additionalUrls定義多個以逗號,分隔的URL。Archaius將首先讀取config.properties,然後按定義的順序讀取系統屬性中定義的所有其他URL。如果有兩個包含相同屬性的URL,則最終值將來自稍後讀取的URL(也就是後放的值覆蓋先放的值)。


示例代碼
public static void main(String[] args) throws InterruptedException {
	// 請注意:這裏必須是file:\\打頭  而不能直接寫D:\\
	// 很多小夥伴說可以這麼寫:
	// -Darchaius.configurationSource.additionalUrls="file:\\D:\\workspaces-mine\\learning\\netflix-learning\\mydemo.properties"
	// 自測無效。請參照源碼:只支持System屬性,而非程序參數 
    System.setProperty("archaius.configurationSource.additionalUrls",
            "file:\\D:\\workspaces-mine\\learning\\netflix-learning\\mydemo.properties");

    DynamicIntProperty myAge = DynamicPropertyFactory.getInstance().getIntProperty("my.age", 18);
    System.out.println(myAge);
    System.out.println(myAge.get());
}

mydemo.properties的內容如下:

my.age=9000

可以看到additionalUrls的值會覆蓋調用主配置config.properties裏的值的。

說明:該配置寫在config.properties裏也是無效的,只能放在系統屬性裏

如果您的應用程序在集羣中運行,則該用例特別有用。通過將其他配置URL定義爲集中式HTTP URL,可以避免在集羣的每個服務器上更改相同配置文件的麻煩。


更改默認設置

其實Archaius的默認配置並不在少數,可以說具體配置項“藏在”源碼處的各個角落,這裏流出幾個主要的默認配置項:

  • archaius.configurationSource.defaultFileName:表示默認加載的配置文件名稱,默認值是config.properties。該配置類也被稱爲主配置
    • 小細節:文件名並不強制要求是.properties結尾,只要是k-v結構就行
  • archaius.fixedDelayPollingScheduler.initialDelayMills:從配置源讀取的初始延遲(以毫秒爲單位),默認值30000。也就是任務啓動後果30s首次執行重新讀取動作
  • archaius.fixedDelayPollingScheduler.delayMills:固定兩次讀取配置URL之間的延遲(以毫秒爲單位),默認值60000。也就是每分鐘執行一次文件的重新讀取動作

這幾個參數配置項可參見URLConfigurationSourceFixedDelayPollingScheduler


高級功能使用(待續)

下面介紹幾個Archaius的高級使用,也就是定製化使用的點。關於這部分本文只是提點,詳細內容會分到後面文章詳解。


自定義配置源或輪詢調度程序

默認情況下,Archaius默認使用一組URL作爲配置源,並以固定的延遲對其進行輪詢。但是,您也可以提供自己的配置源和/或輪詢調度程序。例如,您可以從關係數據庫,分佈式鍵值存儲(如Cassandra)或第三方服務(如你自己的配置中心)定義自己的配置源。

  1. 自定義配置源:默認使用的URLConfigurationSource
public class DBConfigurationSource implements PolledConfigurationSource {
    // ...
    @Override
    public PollResult poll(boolean initial, Object checkPoint)
            throws Exception {
        // implement logic to retrieve properties from DB
    }  
}
  1. 自定義定時調度器:默認使用的是FixedDelayPollingScheduler
public class MyScheduler extends AbstractPollingScheduler {
    // ...
    @Override
    protected synchronized void schedule(Runnable runnable) {
        // schedule the runnable
    }

    @Override
    public void stop() {
        // stop the scheduler
    }
}
  1. 把以上自定義的組件放進DynamicConfiguration裏:
PolledConfigurationSource source = ...
AbstractPollingScheduler scheduler = ...
DynamicConfiguration configuration = new DynamicConfiguration(source, scheduler);
  1. 安裝進配置管理器:
ConfigurationManager.install(configuration);

這樣就可以使用了,形如這樣:

DynamicStringProperty myprop = DynamicPropertyFactory.getInstance().getStringProperty(...);

使用JConsole在運行時查看和更新​​屬性

默認情況下Archaius的JMX功能是關閉的,需要顯示打開才能使用。增加如下配置項:

archaius.dynamicPropertyFactory.registerConfigWithJMX=true

向DynamicPropertyFactory註冊的配置將自動提供給JMX,您可以在其中通過jconsole更新屬性,略。


使用ConfigurationManager配置管理器

配置管理器是管理系統範圍的配置和部署上下文的中心位置。如果您使用自己的AbstractConfiguration進行配置管理,則可以使用ConfigurationManager進行安裝,該管理器負責使用AbstractConfiguration初始化DynamicPropertyFactory。如果您的應用程序沒有以編程方式安裝任何配置,則將懶惰地安裝包含系統屬性和DynamicURLConfiguration的ConcurrentCompositeConfiguration。

部署上下文包含與應用程序部署相關的屬性。例如,DeploymentContext.getDeploymentEnvironment()可以返回諸如“ test”,“ dev”,“ prod”之類的字符串。這對於確定特定部署上下文中使用的屬性集很有用。如果沒有使用ConfigurationManager以編程方式設置部署上下文,則將安裝默認的ConfigurationBasedDeploymentContext。ConfigurationBasedDeploymentContext中API的返回值基於一組屬性值,這些屬性值是從隨ConfigurationManager一起安裝的配置中獲得的。


將Archaius與你自己的Apache Commons Configuration實現一起使用

我們已經知道Archaius它底層是依賴於Apache Commons Configuration來做配置管理的,那麼如果你已經有了自己的一套Apache Commons Configuration實現了怎麼辦呢?這個時候就需要整合嘍

如果您已經使用或擴展了Apache Commons Configuration中的任何類型的AbstractConfiguration,但是想要利用Archaius來爲應用程序提供動態屬性,則可以使用ConfigurationManager通過兩種方式來實現:

  • 使用的實現com.netflix.config.AbstractPollingScheduler來輪詢動態配置源並將其放入您自己的配置中,僞代碼如下:
AbstractConfiguration myConfiguration =  ... ; //這是您的原始配置
// // ... 
AbstractPollingScheduler scheduler =  new  FixedDelayPollingScheduler(); //或使用您自己的調度程序
PolledConfigurationSource source =  new  URLConfigurationSource(); //或使用您自己的源 
scheduler.setIgnoreDeletesFromSource(true; //不要將源中缺少的屬性視爲刪除 
scheduler.startPolling(source,myConfiguration);
// ... 
ConfigurationManager.install(myConfiguration);

現在,原始配置在運行時變爲動態,因爲輪詢的配置源中的屬性將覆蓋原始配置中的值。

  • 使用com.netflix.config.ConcurrentCompositeConfiguration把你的配置組合進來。僞代碼如下:
AbstractConfiguration myConfiguration = ...; // this is your original configuration

// create the dynamic configuration
AbstractPollingScheduler scheduler = new FixedDelayPollingScheduler(); // or use your own scheduler
PolledConfigurationSource source = new URLConfigurationSource(); // or use your own source
DynamicConfiguration dynamicConfig = new DynamicConfiguration(source, scheduler);
    
ConcurrentCompositeConfiguration finalConfig = new ConcurrentCompositeConfiguration();
// add them in this order to make dynamicConfig override myConfiguration
finalConfig.addConfiguration(dynamicConfig);
finalConfig.addConfiguration(myConfiguration);

ConfigurationManager.install(finalConfig);

我個人覺得這麼做是推薦的做法。


總結

初識Archaius的簡單使用和高級使用就先介紹到這,通過本文已經瞭解到了Archaius的作用,以及大概它能怎麼玩,那麼接下來將帶您一起走入它的深入理解之路。

在深入理解Archaius過程中,有一個繞不開的“障礙”便是Apache Commons Configuration,由於前者強依賴於後者進行配置管理。正所謂你對Apache Commons Configuration有多瞭解,決定了你對Netflix Archaius的認識有多深,因此接下來的幾篇內容我將聚焦在Apache Commons Configuration的使用以及深入理解上,一方面能全面的去理解配置管理技術,另一方面能爲更好的認識Archaius打好堅實基礎。
分隔線

聲明

本號所有“享學xxx”系列文章/視頻,和什麼“享學課堂”、“享學科技”無任何關係。只因筆者名字和其重名,僅此而已

  • 原創不易,碼字更不易,你的【三連】是對A哥的最大支持
  • 關注我吧:一個前25年還不會寫Hallo World的半殘程序猿,人送外號:A哥
    • 公衆號:BAT的烏托邦(ID:BAT-utopia)
    • CSDN:BAT的烏托邦
    • 掘金:BAT的烏托邦
    • 騰訊雲+社區:BAT的烏托邦
    • 知識星球:BAT的烏托邦
    • 掃碼/加我wx:fsx641385712,邀你加入[Java高工、架構師]系列純純純技術羣

在這裏插入圖片描述
往期精選

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章