如需為部署在多臺服務器的應用更改配置,在各臺服務器上逐一更改顯然效率太低。您可以使用ACM集中管理配置。ACM會將更新后的配置動態推送到所有服務器。本文結合具體場景介紹此操作流程。
遷移到MSE Nacos
ACM進入下線狀態,所有配置管理相關的需求由MSE中的Nacos承接(ACM獨享版,更好的安全和穩定性)。您需要在ACM控制臺導出配置,然后在MSE控制臺導入之前導出的配置即可完成遷移。具體操作,請參見將應用配置從ACM遷移到MSE Nacos。
前提條件
背景信息
在傳統的配置發布模式下,如果一個應用部署在多臺服務器上,配置變更就需要再在所有服務器上逐一更改,效率低且工作繁瑣。
您可以在ACM中簡化此操作。首先您需要在ACM中為應用創建配置,并在應用中使用ACM的原生API監聽此配置的變更。當您在ACM控制臺更改此配置后,所有部署了該應用的服務器都會收到變更后的配置內容,應用狀態也會隨之刷新。
以下使用示例場景進行說明。
應用myapp.jar部署在生產環境的兩臺服務器上。該應用包含一個配置文件app.cfg,該配置文件包含線程池大小threadPoolSize和日志級別logLevel這兩個配置項。現在需要同時調整該應用在上述兩臺服務器上的配置,并動態刷新應用的狀態。
步驟一:在ACM中創建配置
- 登錄ACM控制臺,在頂部菜單欄選擇地域。
- 在左側導航欄選擇配置列表,在頁面上方選擇命名空間,然后在頁面左側單擊創建配置。
- 在彈出的創建配置面板中填寫配置信息,配置完成后單擊創建。
參數 描述 Data ID 配置ID。建議采用package.class的命名規范,其中class部分是具有業務含義的配置名稱,例如:com.foo.bar.log.level。Data ID在一個Group下是唯一的。 Group 配置分組,建議填寫產品名或模塊名。Group是全局唯一的。 數據加密 您可完成如下配置來統一使用密鑰管理服務(KMS)對配置進行加密: - 打開數據加密。
- 在數據加密區域單擊前往授權。
- 在云資源訪問授權頁面選擇AliyunACMAccessingKMSRole并單擊同意授權。
- 刷新創建配置面板,選擇KMS加密方式。
配置格式 配置內容的數據格式。 配置內容 輸入配置的內容,例如: threadPoolSize=5 logLevel=WARN
配置描述 配置描述信息。 更多配置 - 應用:配置歸屬的應用名。
- 標簽:在文本框中輸入標簽信息,并單擊標簽選擇器。
步驟二:使用ACM原生API監聽配置變更
- 下載樣例工程myapp.zip,或者運行以下命令來創建Maven工程。
mvn archetype:generate -DgroupId=com.acm.sample -DartifactId=myapp -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
創建的工程結構如下:
myapp |-- pom.xml `-- src |-- main | `-- java | `-- com | `-- acm | `-- sample | `-- App.java `-- test `-- java `-- com `-- mycompany `-- app `-- AppTest.java
- 在pom.xml中添加對ACM Client原生API的依賴。
<dependencies> <dependency> <groupId>com.alibaba.edas.acm</groupId> <artifactId>acm-sdk</artifactId> <version>1.0.9</version> </dependency> <!-- 如果已有日志實現,則可去除以下依賴 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.7</version> </dependency> </dependencies>
- 在pom.xml中添加maven-assembly-plugin打包插件。
<plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.4</version> <configuration> <finalName>myapp</finalName> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <appendAssemblyId>false</appendAssemblyId> <archive> <manifest> <mainClass>com.acm.sample.App</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
- 使用ACM Client原生API監聽配置變更。 說明 以下代碼中的$endpoint、$namespace、$accesskey、$secretKey等變量的值,可在ACM控制臺的配置列表頁面獲取和查看。
//-- App.java package com.acm.sample; import java.io.IOException; import java.io.StringReader; import java.util.Properties; import com.alibaba.edas.acm.listener.ConfigChangeListener; import com.alibaba.edas.acm.ConfigService; import com.alibaba.edas.acm.exception.ConfigException; public class App { private static Properties appCfg = new Properties(); public static void initAndWatchConfig() { final String dataId = "com.acm.myapp.app.cfg"; final String group = "myapp"; final long timeoutInMills = 3000; // 從命名空間詳情對話框中拷貝各變量的值Properties properties = new Properties(); properties.put("endpoint", "$endpoint"); properties.put("namespace", "$namespace"); // 如果通過AK/SK訪問ACM properties.put("accessKey", "$accessKey"); properties.put("secretKey", "$secretKey"); // 如果通過ECS實例RAM角色訪問ACM // properties.put("ramRoleName", "$ramRoleName"); // 如果是加密配置,則添加以下兩行進行自動解密 // properties.put("openKMSFilter", true); // properties.put("regionId", "$regionId"); ConfigService.init(properties); // 直接獲取配置內容try { String configInfo = ConfigService.getConfig(dataId, group, timeoutInMills); appCfg.load(new StringReader(configInfo)); } catch (ConfigException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 監聽配置變化,獲取最新推送值ConfigService.addListener(dataId, group, new ConfigChangeListener() { public void receiveConfigInfo(String configInfo) { try { appCfg.load(new StringReader(configInfo)); } catch (Exception e) { // process exception } refreshApp(); } }); } public static void refreshApp() { System.out.println("current thread pool size: " + appCfg.getProperty("threadPoolSize")); System.out.println("current log level: " + appCfg.getProperty("logLevel")); System.out.println(""); } public static void main(String[] args) { initAndWatchConfig(); // 以下代碼用于測試,作用是讓主線程不退出。訂閱配置是守護線程,如果主線程退出守護線程就會退出。while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { } } } }
步驟三:部署并啟動應用
- 在項目根目錄執行以下打包命令,將應用打包成JAR文件,并拷貝到兩臺服務器上。
mvn clean package
- 在Shell中部署并啟動應用。
${JAVA_HOME}/java -cp myapp.jar com.acm.sample.App
步驟四:在ACM控制臺更改配置
- 登錄ACM控制臺,在頂部菜單欄選擇地域。
- 在左側導航欄選擇配置列表,在配置列表頁面選擇創建的配置,然后在操作列單擊編輯。
- 在編輯配置頁面上將配置內容更改為以下內容,并單擊發布。
threadPoolSize=15 logLevel=DEBUG
- 在內容比較對話框中查看更改前后的對比,確認無誤后單擊發布。
執行結果
發布配置之后,部署了myapp應用的兩臺服務器均收到了更新后的配置,并在Console中打印了以下日志。
current thread pool size: 15 current log level: DEBUG