如需为部署在多台服务器的应用更改配置,在各台服务器上逐一更改显然效率太低。您可以使用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