一尘不染

我可以在多个环境中使用单个war文件吗?我是不是该?

jsp

我有一个Java Web应用程序正在工作,我想简化我们如何部署到DEV,QA和PROD环境。

该应用程序在启动时会读取一系列属性,并且dev,qa和prod的属性文件不同。每当我想部署到某个环境时,我都会将特定于环境的属性文件放到我的app文件夹中,进行构建,然后将其部署到三个tomcat
5.5服务器之一。

我想做的就是拥有一个具有所有环境属性的.war,并让应用在初始化过程中询问网络服务器,以弄清应用所处的环境以及要加载的属性。是否有一种简单的方法(或者失败了,一种标准的方法)来做到这一点?


阅读 236

收藏
2020-06-08

共1个答案

一尘不染

这实际上取决于您使用这些属性的目的。

某些容器(例如,数据源)可以在容器本身中配置(Tomcat
5.5。JNDI资源
,另请参见JDBC源部分)。

其他(特定于应用程序)可能确实需要是属性。在这种情况下,您的选择是:

  1. 捆绑WAR文件中的属性,并基于某些外部开关加载适当的子集(环境变量或JVM属性)
  2. 在打开战争包装的每台服务器上设置部署过程,并将属性文件(位于该服务器上的预定义位置并且特定于该服务器)复制到WEB-INF/classes(或其他适当的位置)。

至于“这是否是一个理想的目标”,是的,我想是的。只需进行一次WAR即可进行质量检查/阶段测试,然后部署到生产中,这将减少中间步骤,从而减少出错的机会。

更新 (基于评论):

上面的项目1是指实际的环境变量(例如,您SET ENV_NAME=QA在Windows或ENV_NAME=QA; export ENV_NAMELinux中通过设置的变量)。您可以使用以下代码从代码中读取其值System.getenv()并加载适当的属性文件:

String targetEnvironment = System.getenv("TARGET_ENV");
String resourceFileName = "/WEB-INF/configuration-" + targetEnvironment + ".properties";
InputStream is = getServletContext().getResourceAsStream(resourceFileName);
Properties configuration = new Properties();
configuration.load(is);

但是可以,您可以改为通过JNDI定义标量值(请参阅Tomcat doc中的Environment
Entries
):

<Context ...>
  <Environment name="TARGET_ENV" value="DEV" type="java.lang.String" override="false"/>
</Context>

并通过以下方式在您的应用中阅读

Context context = (Context) InitialContext().lookup("java:comp/env");
String targetEnvironment = (String) context.lookup("TARGET_ENV");
// the rest is the same as above

关键是,如果您仍将使用JNDI,则最好放弃属性文件,并通过JNDI配置所有内容。您的数据源将可用,因为实际资源和基本属性将保持标量(尽管它们将是类型安全的)。

最终,由您决定哪种方法更适合您的特定需求。两者都有优点和缺点。

2020-06-08