Apollo 分散式配置中心(補充)
1. Namespace
1.1. 什麼是Namespace
Namespace是配置項的集合,類似於一個配置檔案的概念。
Apollo在建立專案的時候,都會預設建立一個“application”的Namespace。顧名思義,“application”是給應用自身使用的,熟悉Spring Boot的同學都知道,Spring Boot專案都有一個預設配置檔案application.yml。在這裡application.properties就等同於“application”的Namespace。對於90%的應用來說,“application”的Namespace已經滿足日常配置使用場景了。
1.2. 客戶端如何獲取Namespace
2. 重新構建
git clone https://github.com/ctripcorp/apollo.git
修改完程式碼後呼叫 ${YOUR-WORKSPACE}/apollo/script/build.sh
執行完bulid.sh以後會再各個專案的target目錄下生產zip包
於是,我們就可以得到以下三個包
apollo-adminservice-1.5.0-SNAPSHOT-github.zip
apollo-configservice-1.5.0-SNAPSHOT-github.zip
apollo-portal-1.5.0-SNAPSHOT-github.zip
解壓後修改資料庫連線地址後,啟動
3. 增加可用的環境
前面我們通過執行初始化指令碼來初始化資料庫,在指令碼的最後插入了幾條初始化資料
因此,可以通過修改 apollo.portal.envs 欄位的值來新增啟用的(可用的)環境。直接修改初始化指令碼,或者指令碼執行完以後再執行update。例如:
1 UPDATE ApolloPortalDB.ServerConfig SET value = 'local,dev,test,prod' WHERE id = 1; 2 UPDATE ApolloPortalDB.ServerConfig SET value = '[{"orgId":"TEC","orgName":"技術部"}]' WHERE id = 2;
訪問 http://localhost:8070/ (apollo/admin)
本例中,增加了TEST環境,還增加了一個Namespace
4. API使用方式
API方式是最簡單、高效使用Apollo配置的方式,不依賴Spring框架即可使用。
4.1. 獲取預設namespace的配置
1 // config instance is singleton for each namespace and is never null 2 Config config = ConfigService.getAppConfig(); 3 String someKey = "someKeyFromDefaultNamespace"; 4 String someDefaultValue = "someDefaultValueForTheKey"; 5 String value = config.getProperty(someKey, someDefaultValue);
通過上述的config.getProperty可以獲取到someKey對應的實時最新的配置值。
另外,配置值從記憶體中獲取,所以不需要應用自己做快取。
4.2. 監聽配置變化事件
監聽配置變化事件只在應用真的關心配置變化,需要在配置變化時得到通知時使用,比如:資料庫連線串變化後需要重建連線等。
如果只是希望每次都取到最新的配置的話,只需要按照上面的例子,呼叫config.getProperty即可。
1 // config instance is singleton for each namespace and is never null 2 Config config = ConfigService.getAppConfig(); 3 config.addChangeListener(new ConfigChangeListener() { 4 @Override 5 public void onChange(ConfigChangeEvent changeEvent) { 6 System.out.println("Changes for namespace " + changeEvent.getNamespace()); 7 for (String key : changeEvent.changedKeys()) { 8 ConfigChange change = changeEvent.getChange(key); 9 System.out.println(String.format("Found change - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType())); 10 } 11 } 12 });
4.3. 獲取公共Namespace的配置
1 String somePublicNamespace = "CAT"; 2 Config config = ConfigService.getConfig(somePublicNamespace); 3 String someKey = "someKeyFromPublicNamespace"; 4 String someDefaultValue = "someDefaultValueForTheKey"; 5 String value = config.getProperty(someKey, someDefaultValue);
4.4. 獲取非properties格式namespace的配置
apollo-client 1.3.0版本開始對yaml/yml做了更好的支援,使用起來和properties格式一致。
1 Config config = ConfigService.getConfig("application.yml"); 2 String someKey = "someKeyFromYmlNamespace"; 3 String someDefaultValue = "someDefaultValueForTheKey"; 4 String value = config.getProperty(someKey, someDefaultValue);
5. 實時動態調整日誌級別
這個功能很實用
引入依賴
1 <groupId>com.ctrip.framework.apollo</groupId> 2 <artifactId>apollo-client</artifactId> 3 <version>1.4.0</version> 4 </dependency>
日誌級別配置
1 package com.cjs.example.config; 2 3 import com.ctrip.framework.apollo.Config; 4 import com.ctrip.framework.apollo.model.ConfigChange; 5 import com.ctrip.framework.apollo.model.ConfigChangeEvent; 6 import com.ctrip.framework.apollo.spring.annotation.ApolloConfig; 7 import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener; 8 import lombok.extern.slf4j.Slf4j; 9 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.boot.logging.LogLevel; 11 import org.springframework.boot.logging.LoggingSystem; 12 import org.springframework.context.annotation.Configuration; 13 import org.springframework.util.StringUtils; 14 15 import java.util.Set; 16 17 /** 18 * @author ChengJianSheng 19 * @date 2019-05-31 20 */ 21 @Slf4j 22 @Configuration 23 public class LoggerConfig { 24 25 private static final String LOGGER_TAG = "logging.level."; 26 27 /** 28 * 注入預設的名稱空間配置 29 */ 30 @ApolloConfig 31 private Config config; 32 33 @Autowired 34 private LoggingSystem loggingSystem; 35 36 @ApolloConfigChangeListener 37 private void onChange(ConfigChangeEvent configChangeEvent) { 38 System.out.println("配置發生變化"); 39 System.out.println("Changes for namespace " + configChangeEvent.getNamespace()); 40 for (String key : configChangeEvent.changedKeys()) { 41 ConfigChange change = configChangeEvent.getChange(key); 42 System.out.println(String.format("Found change - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType())); 43 } 44 45 Set<String> keyNames = config.getPropertyNames(); 46 for (String key : keyNames) { 47 if (StringUtils.isEmpty(key)) { 48 continue; 49 } 50 if (!key.startsWith(LOGGER_TAG)) { 51 continue; 52 } 53 54 String loggerName = key.replace(LOGGER_TAG, ""); 55 String strLevel = config.getProperty(key, "info"); 56 LogLevel level = LogLevel.valueOf(strLevel.toUpperCase()); 57 loggingSystem.setLogLevel(loggerName, level); 58 59 log.info("{}:{}", key, strLevel); 60 } 61 } 62 63 }
application.properties
1 server.port=9000 2 3 app.id=1001 4 env=LOCAL 5 apollo.meta=http://localhost:8080 6 apollo.cacheDir=/Users/chengjiansheng/data 7 apollo.bootstrap.enabled=true
修改配置
5. 工程結構
https://github.com/chengjiansheng/apollo-demo
6. 文件
Apollo核心概念之“Namespace”
分散式部署指南
Apollo配置中心的各種使用場景和示例程式碼
Java客戶端使用指南
部署&開發遇到的常見問題
Apollo使用指南
&n