打造环境感知的应用
这里说的环境感知的应用
是指,应用放在不同的环境,就可以使用不同环境的配置,不需要重新打包.
1.我眼中理想的环境和应用
- 应用不用管环境配置
- 参数配置在配置管理系统中的
- 框架从配置管理中加载配置
- 只有操作系统或者应用服务器知道环境的概念
理想很丰满,现实很惨…,揉醒了,继续面对现实.要实现这个目标,还有很多需要做的.现在我们尽可能要做的是,开发童鞋自己把环境搞定,不给其他童鞋添堵.
2.适合我们的环境感知
的应用
我们的系统大多数用的是tomcat作为应用服务器,最好是让应用服务器来提供环境标识,在应用中结合spring profile机制来实现环境感知
3.如何操作
3.1在操作系统中添加环境变量
比如在10测试环境,在/etc/profile
中增加如下东东:
export CATALINA_OPTS=' -Dspring.profiles.active=dev '
然后执行. /etc/profile
解析
3.2配置日志
并不是所有系统都会针对不同环境启用不同的日志配置文件,即便有logback可以很方便的来解决这些问题.
3.2.1 在logback配置内区分环境
比如我们在本地测试的时候,把日志输出到console,便于我们查问题.
可以在logback.xml中加入:
<if condition='property("os.name").toUpperCase().contains("WINDOWS")||property("os.name").toUpperCase().contains("MAC")'>
<then>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{0}:%L-%X{ID}- %msg%n</pattern>
</encoder>
</appender>
<root>
<appender-ref ref="STDOUT" />
</root>
</then>
</if>
上面的配置会在windows和mac中启用console日志输出
在logback中引入外部配置文件,也可以区分不同的环境
<property resource="spring/log/log-${spring.profiles.active}.properties" />
上面会根据spring.profiles.active
的配置读取不同的配置文件
3.2.2 不同环境区分不同的日志配置文件
如果您有针对不同环境不同的日志文件,com.yjf.common.log.LogbackConfigListener
提供了支持.
<context-param>
<param-name>logbackConfigLocation</param-name>
<param-value>WEB-INF/logback-${spring.profiles.active}.xml</param-value>
</context-param>
3.3 配置应用
数据库和外部资源配置,一般会放入到单独的配置文件中,我们可以使用spring提供的能力来实现环境感知
3.3.1 使用properties文件
<bean id="propertyConfigurerForJDBC"
class="com.yjf.common.dal.EncryptablePropertyPlaceholderConfigurer">
<property name="order" value="1" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="location"
value="classpath:jdbc-${spring.profiles.active}.properties" />
</bean>
上面会根据spring.profiles.active
的配置读取不同jdbc配置文件
3.3.2 使用spring profile
<beans profile="production">
<bean id="xxx" class="xxxxBEAN" />
</beans>
<beans profile="test">
<bean id="xxx" class="xxxxBEAN" />
</beans>
spring profile通过读取系统或者环境变量spring.profiles.active
来启用不同的bean.
3.3.2 硬编码实现
com.yjf.common.env.Env
提供了在编写java code时,区分不同的环境
private void doIt() {
if (Env.isOnline()) {
//do anything you like.
}
}
上面的代码只在生成环境运行,com.yjf.common.env.Env
通过读取spring.profiles.active
来判断环境
3.4 配置测试
通过上面的一些列配置,环境都由spring.profiles.active
控制.在本地测试时,也需要启用此环境变量.
3.4.1 tomcat/jetty 启动类
TomcatBootstrapHelper
启动时,默认会在系统变量里增加spring.profiles.active=dev
new TomcatBootstrapHelper(11111).start();
上面的代码会使用dev
环境配置.如果您按照3.3.1配置,此时会读取jdbc-dev.properties
我没有写jetty的启动帮助类,主要原因是为了和线上保持一致,减少一些不可预知的问题.如果要使用jetty,请增加如下代码:
static{
System.setProperty("spring.profiles.active", "dev");
}
3.4.1 单元测试
在测试类或者测试父类中增加:
static{
System.setProperty("spring.profiles.active", "dev");
}