Java Web Deployment:构建代码,还是部署.war?

时间:2008-09-26 20:16:57

标签: java deployment java-ee

部署J2EE / Java Web应用程序的两种主要方式(以非常简单的方式):

将已组装的工件部署到生产框

在这里,我们在其他地方创建.war(或其他),将其配置为生产(可能为多个框创建大量工件),并将生成的工件放在生产服务器上。

  • 优点:生产箱上没有开发工具,可以直接重复使用工件,部署人员不需要构建过程知识
  • 缺点:用于创建和部署工件的两个过程;预先构建的工件的潜在复杂配置可能使进程难以编写脚本/自动化;必须版本二进制工件

在生产框

上构建 工件

此处,用于在开发人员盒上本地构建和部署的相同过程用于部署到生产。

  • 优点:维护的一个过程;并经常使用经过严格测试/验证。在工件创建时可能更容易定制配置,而不是定制预先构建的工件后缀;不需要对二进制工件进行版本控制。
  • 缺点:所有生产箱都需要潜在的复杂开发工具;部署人员需要了解构建过程; 部署您测试的内容

我主要使用第二个进程,不可否认(没有时间/优先级用于另一个部署过程)。就个人而言,我不会购买诸如“生产箱必须清理所有编译器等”之类的论据,但我可以看到部署你测试的内容的逻辑(而不是建立另一个神器)。

但是,Java Enterprise应用程序对配置非常敏感,感觉就像在配置工件的两个过程中遇到麻烦。

思想?

更新

这是一个具体的例子:

我们使用OSCache,并启用磁盘缓存。配置文件必须位于.war文件中,并引用文件路径。每条环境都有不同的路径。构建过程检测用户配置的位置,并确保放置在战争中的属性文件对其环境是正确的。

如果我们要使用构建过程进行部署,那么就需要为生产环境创建正确的配置(例如production.build.properties)。

如果我们遵循“将组装的工件部署到生产框”,我们需要一个额外的过程来提取(不正确的)OSCache属性并将其替换为适合生产环境的属性。

这创建了两个完成同样事情的过程。

所以,问题是:

  • 如果没有“编制生产”,这是否可以避免?
  • 如果没有,这值得吗? “不编译生产”的价值大于“不要重复自己”吗?

7 个答案:

答案 0 :(得分:7)

我坚决反对在生产盒上构建,因为这意味着你使用的是与你测试过的不同的版本。它还意味着每个部署机器都有不同的JAR / WAR文件。如果不出意外,请进行统一构建,以便在进行错误跟踪时,您不必担心服务器之间的不一致。

此外,如果您可以轻松地在构建版本和创建它的源代码之间进行映射,则无需将构建版本置于版本控制中。

在我工作的地方,我们的部署过程如下。 (这是在Linux上,与Tomcat一起使用。)

  1. 测试更改并检查Subversion。 (不一定按照这个顺序;我们不要求提交代码进行测试。我是唯一的全职开发人员,所以SVN树本质上是我的开发分支。你的里程可能会有所不同。)

  2. 将JAR / WAR文件复制到以Subversion修订号命名的共享目录中的生产服务器。 Web服务器只具有读取权限。

  3. 部署目录包含指向修订版目录中文件的相对符号链接。这样,目录列表将始终显示生成运行版本的源代码版本。部署时,我们更新的日志文件只是目录列表。这使得回滚变得容易。 (但有一点要做; Tomcat会根据真实文件的修改日期检查新WAR文件,而不是符号链接,因此我们在回滚时必须触摸旧文件。)

  4. 我们的Web服务器将WAR文件解压缩到本地目录。该方法是可扩展的,因为WAR文件位于单个文件服务器上;我们可以拥有无​​限数量的Web服务器,只进行一次部署。

答案 1 :(得分:3)

我工作过的大部分地方都使用了第一种方法,在战争/耳朵之外单独部署了环境特定的配置信息(并且更加更新)。

答案 2 :(得分:1)

存在配置服务,例如重量级ZooKeeper,并且大多数容器使您能够使用JNDI进行一些配置。这些将配置与构建分开,但可能过度。但是,它们确实存在。很大程度上取决于你的需求。

我还使用了一个进程,通过这个进程构建了包含配置值的占位符。部署WAR时,会爆炸并使用适当的值替换占位符。

答案 3 :(得分:1)

我强烈建议“将已组装的工件部署到生产框”,例如war文件。这就是为什么我们的开发人员使用相同的构建脚本(在我们的例子中为Ant)在他们的开发沙箱上构建战争,就像用于创建finally工件一样。这样就可以调试代码本身,更不用说完全可重复了。

答案 4 :(得分:1)

我支持使用支持分布式构建的持续集成解决方案。检入SCM的代码可以触发构建(用于即时测试),您可以安排构建以创建QA的工件。然后,您可以将这些工件提升为生产并将其部署。

目前,我正在使用AnthillPro进行设置。

编辑:我们现在正在使用Hudson。强烈推荐!

答案 5 :(得分:0)

如果您询问与配置管理相关的此问题,那么您的答案需要基于您认为是托管工件的内容。从CM的角度来看,让一些源文件集合在一个环境中而不是在另一个环境中工作是不可接受的。 CM对环境变量,优化设置,编译器和运行时版本等都很敏感,你必须考虑到这些因素。

如果你问这个问题与可重复的过程创建有关,那么答案需要基于你愿意忍受的疼痛的位置和数量。使用.war文件可能会涉及更多的前期痛苦,以节省测试和部署周期的工作量。使用源文件和构建工具可以节省前期成本,但是在部署过程的后期处理问题时,您将不得不忍受额外的痛苦。

具体示例的更新

相对于你的例子,需要考虑两件事。

  1. .war文件只是一个带有备用扩展名的.zip文件。您可以使用标准zip实用程序替换配置文件。

  2. 可能会重新考虑将配置文件放在.war文件中的必要性。将它放在类路径上还是在服务器启动时在执行命令行中指定了属性是否足够。

  3. 通常,我尝试保持特定于部署位置的部署配置要求。

答案 6 :(得分:0)

使用1个打包的war文件进行部署是一种很好的做法 我们使用ant来替换环境之间不同的值。我们使用@@@变量检查文件,该变量将被我们的ant脚本替换。 ant脚本替换文件中的正确项,然后在部署到每个

之前更新war文件
<replace file="${BUILDS.ROOT}/DefaultWebApp/WEB-INF/classes/log4j.xml" token="@@@" value="${LOG4J.WEBSPHERE.LOGS}"/>


<!-- update the war file We don't want the source files in the war file.-->
<war basedir="${BUILDS.ROOT}/DefaultWebApp" destfile="${BUILDS.ROOT}/myThomson.war" excludes="WEB-INF/src/**" update="true"/>

总结一下,我们使用蚁丘来管理蚂蚁。 ant构建war文件,替换文件路径,更新war文件,然后部署到目标environement。一个过程,实际上是在蚁丘上点击一下按钮。