最近遇到一些开发者朋友, 准备将原有的 Java Spring 的应用配置迁移到 阿里云应用配置管理 ACM 中. 迁移过程中, 遇到不少有趣的问题. 本文将通过一个简单的样例来还原迁移过程中遇到的问题和相关解决思路, 以期达到和读者交流的目的.
什么样的配置适合进入配置中心
这是所有准备迁移配置到配置中心的用户遇到的第一个问题. 我们将从时效性和安全这两个维度进行分析.
时效性: 静态 VS 动态
静态配置是指程序版本一旦发布, 基本上不会修改的配置内容, 例如:
软件版本号: 显然版本号一经确定, 产品基本上不需要改.
日志样式: 日志的 layout, 如时间戳, 文件名, 日志级别等排版, 基本上也不需要大改.
三方软件 LicenseKey: 基本上也是一经发布, 很少变化. 不排除中途三方软件 License 升级, 但是这种升级一般都可以根据软件重新发版来解决配置变更.
PaaS 平台连接串: 如数据库连接串, 中间包含数据库, 用户名和密码等. 除非因为合规原因修改密码, 或者数据发生迁移等, 否则也是很少变化.
动态配置是指程序运行时的一些配置变化, 通常会影响到程序的一些运行行为, 例如:
限流降级参数: 限流降级参数一般都不太固定. 系统一般在运行时最好是需要根据实际 workload pattern 来动态调节限流参数如阈值 RT, 峰值 TPS, 等.
监控报警阈值: 如交易环比下跌 20% 产生 error 报警, 下跌 50% 产生 critical 报警. 对于监控系统来讲, 线上业务特征由于变化比较频繁, 因此一般也不将报警的阈值写死,
日志打印级别: 线上一旦出现诡异的行为, 希望吧日志打印级别从 error 比如调高到 debug, 一般都比较希望能动态的去调整, 而不需要重启应用.
容灾多活: 一旦站点反生灾难, 一定是希望切换是越快越好. 因此配置必须动态秒级生效, 尽可能降低资损.
从时效性的维度来讲, 一般建议用户把静态配置存放到自己文件中, 尽可能保持简单, 但是需要把动态配置放到配置中心里, 以加强灵活性和应用动态变更的实效性.
安全: 非敏感 VS 敏感
非敏感配置一般指偏向技术类, 暴露后不会导致配置上的安全隐患, 例如:
软件版本号: 跟产品迭代相关, 无业务属性, 非敏感配置.
日志样式: 一般跟程序事后诊断相关, 非敏感配置.
日志打印级别: 影响日志打印的多或少, 非敏感配置.
限流降级参数: 限流降级主要为维持内部应用稳定, 非敏感配置.
监控报警阈值: 主要是影响业务的报警精度, 非敏感配置.
容灾多活: 一般和数据主备配置和业务分片相关, 非敏感配置.
敏感配置通常和业务数据相关, 一旦泄露将引起安全隐患, 例如:
三方软件 LicenseKey: 一旦泄露容易发生 LicenseKey 被盗用, 为敏感配置.
PaaS 平台连接串: 典型如数据库连接串, 一旦泄露, 无论内部或外部用户, 都可以很容易地登到业务数据库接触到业务敏感信息, 为敏感配置.
从安全的维度来看, 我们通常建议用户把非敏感配置存放到自己的文件中, 尽可能保持简单, 但是需要把敏感配置放到配置中心里, 并加密且做好鉴权, 尽量不要让无关人员接触到.
时效性和安全分析总结
基于 Spring 框架的 Java 应用配置如何迁移
使用 Spring 框架的 Java 开发者一般经常用到的一种配置注解姿势是利用 Spring 的 @value 注解.
原始的纯静态文件场景
例如这个配置, 包含两个配置参数, 一个是软件的版本号, 一个是数据库连接串:
通过 @PropertySource 和 @value 的注解来自动注入配置.
- @Configuration
- @ComponentScan("com.alibaba")
- @PropertySource("classpath:myApp.properties")
- public class AppConfig {
- @Value(value="${url}")
- private String URL;
- @Value(value="${dbuser}")
- private String USER;
- @Value(value="${driver}")
- private String DRIVER;
- @Value(value="${dbpassword}")
- private String PASSWORD;
- @Value(value="${appVersion}")
- private String version;
- }
以上代码省略了相关数据库连接初始化等操作.
开始配置迁移, 进入混合配置场景
目前由于安全合规或配置时效等原因, 要开始迁移配置到 ACM 上. 经过分析, 我们发现部分数据库的配置最好迁移到 ACM, 以红色字体标注. 红色部分将全部被迁移到 ACM 中.
接下来主要三个改动, 先归纳下.
在 ACM 控制台种增加相关配置的记录.
Java 工程包中增加 ACM SDK 相关依赖.
少许修改代码, 增加在 ACM 中取配置的注解代码.
第一步, 直接到 ACM 中创建配置项, 名字为 myapp.dbconfig.properties, 并把配置内容编辑在对应编辑框中. 详细操作指南请参见 ACM 快速入门文档, 操作截图如下.
第二步, 在 maven 的 pom.xml 中增加依赖, 如下.
- <dependency>
- <groupId>com.alibaba.nacos</groupId>
- <artifactId>nacos-spring-context</artifactId>
- <version>0.2.1- RC1</version>
- </dependency>
第三步, 在对应 AppConfig.java 代码中植入 API 注解, 通过 ACM 去获取动态配置. 代码增加部分如红色字体部分.
- @Configuration @ComponentScan("com.journaldev")
- @PropertySource("classpath:myApp.properties")
- @EnableNacosConfig(globalProperties =
- @NacosProperties(endpoint = "acm.aliyun.com", namespace = "xxx", accessKey = "xxx", secretKey = "xxx"))
- @NacosPropertySource(dataId = "myApp.dbconfig.properties", autoRefreshed = true) public class AppConfig {
- @Value(value="${url}") private String URL;
- @Value(value="${dbuser}") private String USER;
- @Value(value="${driver}") private String DRIVER;
- @Value(value="${dbpassword}") private String PASSWORD;
- @Value(value="${appVersion}")
- private String version; public String getVersion() {
- return version;
- }
- }
至此, 改动结束. 通过 ACM SDK 支持 Spring 的 @value 注解能力, 代码几乎 0 改动.
几点注意事项
在以上代码实例中, 有几样事情需要注意:
代码中使用的 ACM SDK 为 Nacos SDK.Nacos (http://nacos.io) 为 ACM 的开源实现, ACM 无缝兼容所有 Nacos 的接口.
在代码示例中, 使用了明文注解来写死 ACM 的 endpoint, namespace, AK, SK, 等等. 在实际操作种, 相关变量其实不用写死.
endpoint namespace 等可以通过 ACM 的相关文件配置或系统变量来解决. 详情参见: https://help.aliyun.com/document_detail/60138.html
AK, SK 等敏感信息可以通过 ECS Ram Role 功能来让系统自行判断, 代码不用写死. 详情参见: https://help.aliyun.com/document_detail/72013.html
代码中未包含动态配置监听的回调部分. 基于 Spring 的动态配置相关使用方法请参见:
更多信息
代码实例下载链接
提取密码: gy57
如果您对阿里云应用配置管理 ACM 的开源版产品 Nacos 感兴趣, 请访问我们的官网网站, 或是扫描以下二维码加入我们.
来源: https://yq.aliyun.com/articles/674432