我目前正在开发一个 j2ee 项目,该项目已经处于测试阶段一段时间了。目前我们正在解决部署过程中的一些问题。具体来说,war 中嵌入了许多文件(一些 xml 文件和 .properties),根据您是否处于开发、测试或生产环境,需要部署不同的版本。像日志级别、连接池等。

所以我想知道这里的开发人员如何构建部署 Web 应用程序的流程。您是否将尽可能多的配置卸载到应用程序服务器?您是否在部署之前以编程方式替换设置文件?在构建过程中选择版本?手动编辑战争?

另外,您在通过应用程序服务器的静态库提供依赖项方面走了多远,以及您在战争中投入了多少?所有这些只是为了了解目前常见(或可能是最佳)实践是什么。

有帮助吗?

解决方案

我在一个单独的服务器团队执行我们的应用程序的质量保证和生产服务器的配置的环境中工作。每一个应用一般部署在QA两台服务器,并在生产三台服务器。我的开发团队已经发现,最好是通过把尽可能多的配置尽可能在战争中(或耳)到服务器上需要的配置的量最小化。这使得服务器配置更加简单,也最大限度地减少了服务器团队将错误地配置服务器的机会。

我们没有具体的机器配置,但我们确实有环境特定的配置(开发,QA和生产)。我们必须存储在由环境(例如:dev.properties,qa.properties,prod.properties)命名为war文件的配置文件。我们把服务器虚拟机的java命令行上的-D属性指定的环境(例如:Java的-Dapp.env =督促...)。该应用程序可以查找app.env系统属性,并使用它来确定该名称的属性文件来使用。

我想,如果你有一个少数特定的机器性能,那么你可以指定它们作为-D性能以及。共享配置提供了一种简单的方法来属性文件与系统性能结合起来。

我们在服务器上配置的连接池。我们命名连接池的各种环境相同,只是指向被分配给每个环境到适当的数据库服务器。该应用程序只需要知道一个连接池名称。

其他提示

我认为,如果属性是机器/特定部署,则它们所属的机器上。如果我要在战争包东西,它应该是落innable,这意味着什么,是专门针对它的运行机器。这种想法将打破如果战争中有依赖于机器的性能。

我喜欢做的是建立一个properties.example文件的项目,每台机器都有一个的.properties是住的地方战争可以访问它。

的另一种方法是将有蚂蚁的任务,例如对于开发战,舞台战,督促战,并有项目,在战争中建造烤的性质部分的套。我不喜欢这种尽可能多的,因为你会最终有一个单独的服务器上的东西一样的文件位置,你的项目的一部分。

我认为wrt配置文件 史蒂夫的 答案是迄今为止最好的答案。我会添加相对于 war 文件的安装路径制作外部文件的建议 - 这样您就可以在一台具有不同配置的服务器上安装多个 war。

例如如果我的 dev.war 被解压成 /opt/tomcat/webapps/dev, ,那么我会用 ServletContext.getRealPath 找到基本文件夹和 war 文件夹名称,然后配置文件将位于 ../../config/dev 相对于战争,或 /opt/tomcat/config/dev 为绝对。

我也同意 账单 关于在这些外部配置文件中放置尽可能少的内容。根据您的环境使用数据库或 JMX 来存储尽可能多的数据。Apache Commons 配置有一个 好东西 用于处理数据库表支持的配置。

关于图书馆,我同意 未知 拥有所有库 WEB-INF/lib 文件夹中的war文件(自打包)。优点是应用程序的每次安装都是自主的,并且您可以同时使用不同版本的库来构建不同的战争。

缺点是它会使用更多内存,因为每个 Web 应用程序都有自己的类副本,由自己的类加载器加载。

如果这确实引起了关注,那么您可以将 jar 放在 servlet 容器的公共库文件夹中($CATALINA_HOME/lib 对于雄猫)。不过,在同一服务器上运行的所有 Web 应用程序安装都必须使用相同版本的库。(实际上,这并不完全正确,因为您可以将覆盖版本放在个人中 WEB-INF/lib 如有必要,请保存文件夹,但这会变得非常混乱。)

在这种情况下,我将使用 InstallShield 或为公共库构建一个自动安装程序 国家信息安全局 或适用于您的操作系统的同等版本。可以轻松判断您是否拥有最新的库集以及升级、降级等。

我通常制作两个属性文件:

  • 一个用于嵌入应用程序中的应用程序细节(消息、内部“魔法”单词),
  • 另一个用于在每个服务器的类路径上公开的环境细节(数据库访问、日志级别和路径...)并“粘住”(不随我的应用程序一起提供)。通常我会根据目标环境“mavenise”或“anttise”这些值来放置特定值。
  • 很酷的人使用 JMX 来维护他们的应用程序配置(配置可以实时修改,无需重新部署),但它对于我的需求来说太复杂了。

服务器的(静态?)库:我强烈建议不要在我的应用程序中使用服务器库,因为它会增加对服务器的依赖:

  1. IMO,我的应用程序必须是“自打包”的:放弃我的战争,仅此而已。我见过有 20 Mb 罐子的战争,这对我来说并不令人不安。
  2. 常见的最佳实践是将外部依赖限制为 J2EE 教条所提供的内容:J2EE API(使用 Servlet、Ejbs、Jndi、JMX、JMS...)。您的应用程序必须“与服务器无关”。
  3. 将依赖项放入您的应用程序中(war、ear、wathever)是自我记录的:您知道您的应用程序依赖哪些库。使用服务器库,您必须清楚地记录这些依赖关系,因为它们不太明显(很快您的开发人员就会忘记这个小魔法)。
  4. 如果您升级应用程序服务器,您所依赖的服务器库也可能会发生变化。AppServer 编辑器不应该维护其内部库在各个版本之间的兼容性(大多数时候,他们不这样做)。
  5. 如果您使用应用服务器中嵌入的广泛使用的库(想到了 jakarta commons 日志记录,又名 jcl),并且想要升级它的版本以获得最新功能,那么您将面临应用服务器不支持它的巨大风险。
  6. 如果您依赖于静态服务器对象(在服务器类的静态字段中,例如地图或日志),您必须重新启动应用程序服务器才能清理此对象。您失去了热重新部署应用程序的能力(旧服务器对象在重新部署之间仍然存在)。使用应用程序服务器范围的对象(J2EE 定义的对象除外)可能会导致细微的错误,特别是当该对象在多个应用程序之间共享时。这就是为什么我强烈反对使用驻留在 appServer 库的静态字段中的对象。

如果您绝对需要“此应用程序服务器的 jar 中的此对象”,请尝试将 jar 复制到您的应用程序中,希望不依赖其他服务器的 jar,并检查应用程序的类加载策略(我习惯将“父级最后”类加载我所有应用程序的政策:我确信我不会被服务器的罐子“污染” - 但我不知道这是否是“最佳实践”)。

我把所有的配置在数据库中。容器(Tomcat的中,WebSphere等),让我获得了初始数据库连接,并从那时起,一切都散发出来的数据库。这允许多个环境,群集和动态变化无需停机(或至少不具有重新部署)。特别好是能够动态更改的日志级别(虽然您将需要一个管理界面或背景复习拿起变化)。显然,这仅适用于那些不需要的启动的事情,但通常,你可以在启动后获取数据库很快。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top