我可以在多个环境中使用单个war文件吗?我是不是该? [英] Can I use a single war file in multiple environments? Should I?

查看:81
本文介绍了我可以在多个环境中使用单个war文件吗?我是不是该?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的工作中有一个Java Web应用程序,我想简化我们部署到DEV,QA和PROD环境的方式。



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



我想要做的是必须有一个.war,它具有所有环境的属性,并让应用程序在初始化过程中询问Web服务器,以确定应用程序所处的环境,从而要加载的属性。是否有一种简单的方法(或者说,这是一种标准的方式)?

解决方案

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



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



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


  1. 在WAR文件中捆绑属性并根据某些外部开关(环境变量或JVM)加载适当的子集属性)

  2. 在解压为war的每台服务器上设置部署过程,并将属性文件(位于该服务器上的预定义位置,特定于该服务器)复制到 WEB-INF / classes (或其他适当的地方)。

至于这是一个理想的目标 - 是的,我想是的。在QA / staging中测试单个WAR然后部署到生产中会减少一个中间步骤,从而减少出错的可能性。



更新(基于评论):



上面的项目#1是指一个实际的环境变量(例如你通过 SET ENV_NAME = QA <设置的东西Windows中的/ code>或 ENV_NAME = QA;在Linux中导出ENV_NAME 。您可以使用 System.getenv()从代码中读取其值并加载相应的属性文件:

  String targetEnvironment = System.getenv(TARGET_ENV); 
String resourceFileName =/ WEB-INF / configuration-+ targetEnvironment +。property;
InputStream is = getServletContext()。getResourceAsStream(resourceFileName);
属性配置=新属性();
configuration.load(is);

但是,您可以通过JNDI定义标量值(请参阅Tomcat doc中的环境条目):

 <上下文...> 
< Environment name =TARGET_ENVvalue =DEVtype =java.lang.Stringoverride =false/>
< / Context>

并在您的应用中通过



<$来阅读p $ p> Context context =(Context)InitialContext()。lookup(java:comp / env);
String targetEnvironment =(String)context.lookup(TARGET_ENV);
//剩余部分与上面相同

事情是,如果你将是无论如何,使用JNDI,您可能会放弃您的属性文件并通过JNDI配置所有内容。您可以使用您的数据源作为实际资源,基本属性仍然是标量(尽管它们是类型安全的)。



最终由您决定哪种方式更适合您的特定需求;两者都有利弊。


I have a Java web application at my work and I'd like simplify how we deploy to our DEV, QA, and PROD environments.

The application reads in a series of properties at startup, and the properties files are different for dev, qa, and prod. Whenever I want to deploy to a certain environment I drop the environment-specific properties file into my app folder, build the war, and then deploy it to one of the three tomcat 5.5 servers.

What I would like to do is have to have a single .war that has the properties for all environments, and have the app interrogate the webserver during the init process to figure out which environment the app is in, and hence which properties to load. Is there an easy way (or, failing that, a standard way) to do that?

解决方案

This really depends on what you are using those properties for.

Some (like data source, for example) can be configured in the container itself (Tomcat 5.5. JNDI Resources, see JDBC sources section as well).

Others (application-specific) may indeed need to be properties. In which case your choices are:

  1. Bundle properties within WAR file and load the appropriate subset based on some external switch (either environment variable or JVM property)
  2. Setup a deployment process on each of your servers where war is unpacked and a property file (located in a predefined location on that server and specific to that server) is copied over to WEB-INF/classes (or other appropriate place).

As far as "is this a desirable goal" goes - yes, I think so. Having a single WAR to test in QA / staging and then deploy to production cuts out an intermediate step and thus leaves less chances for mistakes.

Update (based on comment):

Item #1 above refers to an actual environment variable (e.g. something that you set via SET ENV_NAME=QA in Windows or ENV_NAME=QA; export ENV_NAME in Linux). You can the read its value from your code using System.getenv() and load the appropriate properties file:

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);

But yes, you can instead define a scalar value via JNDI (see Environment Entries in Tomcat doc) instead:

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

and read it within your app via

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

The thing is, if you will be using JNDI anyway, you might as well forgo your property files and configure everything via JNDI. Your data sources will be available to you as actual resources and basic properties will remain scalars (though they will be type safe).

Ultimately it's up to you to decide which way is better for your specific needs; both have pros and cons.

这篇关于我可以在多个环境中使用单个war文件吗?我是不是该?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆