配置转存到环境变量
由于最近上线总是出现问题,而上线规范还要求“一包到底”,这就导致如果上线包出错会导致重新准备包将重新走一遍上线流程,而仅仅是修改配置的话这样反而显得得不偿失,所以沟通后决定将生产包中的配置和代码分离开来,每次上包只包含代码,这样配置抽离存放就有两种方案,一种是放在云平台读取,另一种就是放在环境变量中。
如果是放在微服务中来讲,将配置放在 Nacos 或 Spring Cloud Config 上是为了方便集中管理,而且使用这种框架也可以动态更新配置,最根本的原因还是为了多环境和多实例的支持,让多台环境不用重复配置相同的配置。可现在像一些 Spring MVC 的老项目完全没有这种需求,基本都是打 war 包双活部署,而且并没有这种云配置的框架支持,所以我们决定把 .properties 中的配置迁移到环境变量读取。
实操
如果 Spring MVC 项目一切用法都规范的话,大部分 .properties 中的配置读取都是在 xml 中用 ${} 占位符读取出来的,至于加载 .properties 则是用下面这种方式读取配置的。
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:config.properties" /></bean>当我们全部将 .properties 中的变量添加到环境变量中后,把项目中的 .properties 全部删除并且把上面读取的 bean 也删除掉后启动,发现项目从环境变量中读取的 value 全部都是 String 类型,当你一些端口一类的变量需要其他类型的时候,在转换的时候会出现问题,这个问题的解决方法就是加一个空的上面占位符所读取的类,让 Spring 这个类帮我们做类型转换即可。
如果有些项目并不规范,有些配置是调用 ClassLoader() 读取文件获取的配置,这些就要用到 System.getenv() 方法获取到环境变量的 Map ,然后匹配赋值即可。不过这个方法有个弊端,无论是 Windows 还是 Liunx ,这个方法只能获取到全局(root)的变量,获取不到个人用户下的环境变量,所以在移动环境变量的时候尽量配置到全局变量中去。
总结
虽然成功把配置和代码从包中分离出来了,但是只能说是符合当前公司的使用场景,至于是不是最优解还尚且未知,希望以后可以学习到其他更优实践。