打造环境感知的应用

January 15, 2014

打造环境感知的应用

这里说的

1
环境感知的应用
是指,应用放在不同的环境,就可以使用不同环境的配置,不需要重新打包.

1.我眼中理想的环境和应用

  • 应用不用管环境配置
  • 参数配置在配置管理系统中的
  • 框架从配置管理中加载配置
  • 只有操作系统或者应用服务器知道环境的概念

理想很丰满,现实很惨…,揉醒了,继续面对现实.要实现这个目标,还有很多需要做的.现在我们尽可能要做的是,开发童鞋自己把环境搞定,不给其他童鞋添堵.

2.适合我们的
1
环境感知
的应用

我们的系统大多数用的是tomcat作为应用服务器,最好是让应用服务器来提供环境标识,在应用中结合spring profile机制来实现环境感知

3.如何操作

3.1在操作系统中添加环境变量

比如在10测试环境,在

1
/etc/profile
中增加如下东东:

1
export CATALINA_OPTS=' -Dspring.profiles.active=dev '

然后执行

1
. /etc/profile
解析

3.2配置日志

并不是所有系统都会针对不同环境启用不同的日志配置文件,即便有logback可以很方便的来解决这些问题.

3.2.1 在logback配置内区分环境

比如我们在本地测试的时候,把日志输出到console,便于我们查问题. 可以在logback.xml中加入:

1
2
3
4
5
6
7
8
9
10
11
12
<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中引入外部配置文件,也可以区分不同的环境

1
<property resource="spring/log/log-${spring.profiles.active}.properties" />

上面会根据

1
spring.profiles.active
的配置读取不同的配置文件

3.2.2 不同环境区分不同的日志配置文件

如果您有针对不同环境不同的日志文件,

1
com.yjf.common.log.LogbackConfigListener
提供了支持.

1
2
3
4
<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文件
1
2
3
4
5
6
7
<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>

上面会根据

1
spring.profiles.active
的配置读取不同jdbc配置文件

3.3.2 使用spring profile
1
2
3
4
5
6
<beans profile="production">
 	<bean id="xxx" class="xxxxBEAN" />  
</beans>
<beans profile="test">
 	<bean id="xxx" class="xxxxBEAN" />  
</beans>

spring profile通过读取系统或者环境变量

1
spring.profiles.active
来启用不同的bean.

3.3.2 硬编码实现

1
com.yjf.common.env.Env
提供了在编写java code时,区分不同的环境

1
2
3
4
5
    private void doIt() {
    	if (Env.isOnline()) {
    		//do anything you like.
        }
	}

上面的代码只在生成环境运行,

1
com.yjf.common.env.Env
通过读取
1
spring.profiles.active
来判断环境

3.4 配置测试

通过上面的一些列配置,环境都由

1
spring.profiles.active
控制.在本地测试时,也需要启用此环境变量.

3.4.1 tomcat/jetty 启动类

1
TomcatBootstrapHelper
启动时,默认会在系统变量里增加
1
spring.profiles.active=dev

1
new TomcatBootstrapHelper(11111).start(); 上面的代码会使用`dev`环境配置.如果您按照3.3.1配置,此时会读取`jdbc-dev.properties`

我没有写jetty的启动帮助类,主要原因是为了和线上保持一致,减少一些不可预知的问题.如果要使用jetty,请增加如下代码:

1
2
3
static{
	System.setProperty("spring.profiles.active", "dev");
}
3.4.1 单元测试

在测试类或者测试父类中增加:

1
2
3
static{
	System.setProperty("spring.profiles.active", "dev");
}

一次技术问答

## 一次技术问答最近一年多都没有写博客了,技术上做了很多有意义的事情,也有一些经验上的积累,逐步沉淀到博客上。今天回答某公司的技术上的一些疑问,把问题和回答贴上来。逐步`养`自己的技术观。### 1. 如何做数据安全防范?还有哪些支付安全需要注意?数据安全防范主要分为两个...… Continue reading

2016年05月Reading Notes

Published on August 10, 2016

2016年05月Reading Notes

Published on June 19, 2016