在之前的系列講過Hystrix的核心實現源碼,多次提及到Archaius(Netflix公司開源項目之一),其實Netflix的所有組件都是通過它獲取配置。Archaius主要用於多配置存儲的動態獲取,基於對apache common configuration類庫的擴展。
//比如Hystrix有使用
public class HystrixPlugins {
private static Object getPluginImplementationViaArchaius(Class<?> pluginClass) {
String classSimpleName = pluginClass.getSimpleName();
// Check Archaius for plugin class.
String propertyName = "hystrix.plugin." + classSimpleName + ".implementation";
//這裏有使用
String implementingClass = DynamicPropertyFactory.getInstance().getStringProperty(propertyName, null).get();
if (implementingClass != null) {
...
}
}
//配置管理類核心實現
public class DynamicPropertyFactory {
private static DynamicPropertyFactory instance = new DynamicPropertyFactory();
public DynamicStringProperty getStringProperty(String propName, String defaultValue) {
return this.getStringProperty(propName, defaultValue, (Runnable)null);
}
public DynamicStringProperty getStringProperty(String propName, String defaultValue, Runnable propertyChangeCallback) {
checkAndWarn(propName);
DynamicStringProperty property = new DynamicStringProperty(propName, defaultValue);
addCallback(propertyChangeCallback, property);
return property;
}
}
它有如下一些特性:
- 動態類型化屬性
- 效和線程安全的配置操作
- 輪詢框架(允許獲取配置源屬性的更改)
- 配置改變時的回調機制
- JMX,通過Jconsole檢查和調用操作屬性
- 複合配置(具有有序的層次結構)
- 對URLs, JDBC and Amazon DynamoDB等動態配置源的實現
- scala動態屬性包裝器
1. Getting Archaius
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<version>0.6.0</version>
</dependency>
2. 使用本地文件作爲配置源
有兩種方法可以讓Archaius通過使用本地配置文件嚮應用程序提供動態屬性來實現開箱即用的工作。
- 默認情況下,Archius將在應用程序的類路徑上查找名爲“config.properties”的文件,並將其內容作爲配置屬性讀取。該文件也可以在JAR文件的根目錄中。
- 此外,你也可以通過系統配置參數““archaius.configurationSource.additionalUrls””定義一個本地文件全路徑,如:-Darchaius.configurationSource.additionalUrls=file:///apps/myapp/application.properties
DynamicLongProperty timeToWait = DynamicPropertyFactory.getInstance().getLongProperty("lock.waitTime", 1000);//默認值爲1000
timeToWait.get();//獲取值
默認的:Archaius會每一分鐘去重新加載下屬性配置,多屬性文件時的屬性會覆蓋(最後讀到的屬性會覆蓋前面相同的屬性)
3. 更改默認設置
Operation | HTTP action | Notes |
archaius.configurationSource.defaultFileName | 指定Archaius默認加載的配置源屬性文件名,默認:classpath:config.properties | config.properties |
archaius.fixedDelayPollingScheduler.initialDelayMills | 延遲加載,默認30秒 | 30000 |
archaius.fixedDelayPollingScheduler.delayMills | 兩次屬性讀取時間間隔,默認1分鐘 | 60000 |
4. 用戶指南
默認情況下,Archius使用一組URL作爲配置源,並以固定的延遲對其進行輪詢。但是,您也可以提供自己的配置源和/或輪詢調度程序。例如,您可以從關係數據庫、分佈式鍵值存儲(如Cassandra)或第三方服務(如AWS SimpleDB)定義自己的配置源。
public class DBConfigurationSource implements PolledConfigurationSource {
// ...
@Override
public PollResult poll(boolean initial, Object checkPoint)
throws Exception {
// implement logic to retrieve properties from DB
}
}
public class MyScheduler extends AbstractPollingScheduler {
// ...
@Override
protected synchronized void schedule(Runnable runnable) {
// schedule the runnable
}
@Override
public void stop() {
// stop the scheduler
}
}
PolledConfigurationSource source = ...
AbstractPollingScheduler scheduler = ...
DynamicConfiguration configuration = new DynamicConfiguration(source, scheduler);
ConfigurationManager.install(configuration);
DynamicStringProperty myprop = DynamicPropertyFactory.getInstance().getStringProperty(...);
4.1 DeploymentContext
DeploymentContext定義一組基於部署上下文的屬性。這些屬性的值是可選的,可以是任何字符串。例如,環境是部署上下文的一個屬性,可以是“prod”、“test”或對組織有意義的任何其他字符串,簡單的講就是多環境上可以使用。
4.2 ZooKeeper配置
此實現需要指向包含配置屬性層次結構的zk根父節點的路徑。所有服務器都將收到zk watcher回調,並自動更新其值,類似於其他動態配置源。
String zkConfigRootPath = "/[my-app]/config";
CuratorFramework client CuratorFrameworkFactory.newClient(zkConnectionString, new ExponentialBackoffRetry(1000, 3));
ZooKeeperConfigurationSource zkConfigSource = new ZooKeeperConfigurationSource(client, zkConfigRootPath);
zkConfigSource.start();
DynamicWatchedConfiguration zkDynamicConfig = new DynamicWatchedConfiguration(zkConfigSource);
ConfigurationManager.install(zkDynamicConfig);
//讀取節點屬性值/[my-app]/config/com.fluxcapacitor.my.property
String myProperty = DynamicPropertyFactory.getInstance().getStringProperty("com.fluxcapacitor.my.property", "<none>").get();
4.3 動態配置校驗
應用程序可以定義應用於動態屬性值的驗證規則。如果在更新動態屬性期間驗證失敗,則將引發RuntimeException,並且動態屬性的值將保持不變。
DynamicIntProperty validatedProp = new DynamicIntProperty("abc", 0) {
@Override
public void validate(String newValue) {
if (Integer.parseInt(newValue) < 0) {
throw new ValidationException("Cannot be negative");
}
}
};
總結,關於java的配置管理類庫,Archaius是其中一個實現版本,spring-boot 也有自己的實現,它叫Spring Boot external config。由此可以看出,在spring cloud netflix的組件時要特別關注這一點!