Java Web应用程序配置模式

2021/01/11 03:11 · java ·  · 0评论

是否有任何模式或最佳实践可用于简化跨多个环境的Java Web应用程序的配置文件更改。例如JDBC URL,SOAP端点等。

为了帮助澄清我的问题,我使用了一些大型Java Web应用程序作为背景知识,这些Web应用程序在任何给定的发行周期内都会在6种不同的环境中移动。开发,集成,质量保证,性能,并最终部署到多个生产服务器。在每种环境中,配置都需要更改。目前,每个部署的大多数配置更改都是手动完成的,既费时又容易出错。

有什么办法可以使手动干预摆脱这一过程?

最近,我倾向于使用.NET进行更多工作,因此我的Java相当生锈。我非常确定,只要稍加调整,它就可以在任何语言中使用。

我们使用.NET配置系统的扩展,该扩展允许我们将环境和/或应用程序特定的设置与更全局的配置结合使用。配置系统使用全局设置,以便每台计算机将其标识为开发,测试版或生产(默认)。依次加载的一组文件以及最后一个文件中的设置将覆盖先前加载的文件中定义的任何设置。文件按以下顺序加载:

  1. 全局设置
  2. 特定于应用程序的设置
  3. 特定于应用程序的环境覆盖

所有文件都在源代码控制中,并且由于环境是在计算机上定义的,因此应用程序正在运行;由于除非机器配置将其标识为“ beta”,否则它将无法访问“ beta”配置,因此我们可以升级所有配置文件,而不必担心无意间将生产应用程序指向dev数据库。

我很惊讶没有人引用Jakarta Commons Configuration API(http://commons.apache.org/configuration/)来回答这个问题。它允许您具有文件层次结构(或其他配置源,如XML,JNDI,JDBC等)。这就是杰里米·塞吉(Jeremy Seghi)所说的,它为您提供了同时具有默认值和本地替代值的好方法。

最好的部分是,它是一种经过测试的有效解决方案,因此您不必自己动手做一些事情。

这是我使用或遇到的一些可能的做法。在实践中通常需要将这些结合起来。

构建时用conffile替换变量值

这是使用Apache Ant可以完成此操作的示例。${var.name}可以通过构建配置文件来控制Ant属性():

<filterset id="variables.to.replace">
    <filter token="APPNAME" value="${app.name}"/>
    <filter token="WEBAPP-PATH" value="${webapp.path}"/>
    <filter token="ENCRYPT-ALGORITHM" value="${encrypt.algorithm}"/>
    <filter token="ERROR-MAILTO" value="${error.mailTo}"/>
    <!--...-->
</filterset>

<!-- Then, when building & copying the conf, replace the variables: -->
<copy todir="${properties.target.dir}">
    <!-- env specific conf files -->
    <fileset dir="${basedir}/env/${run.env}/webapp/WEB-INF/classes" />
    <filterset refid="variables.to.replace"/>
</copy>

好消息是,您可以在构建时很好地控制不同的配置。不好的是,如果将这种方法广泛用于大量不同的配置,则系统会变得非常复杂且难以维护。同样,必须构建conffile也意味着较慢的开发周期。

在Webapp启动时将conf变量替换为war内部的conf

即使只有一种可能的配置,这也是我通常使用Spring Framework时所做的事情,从而获得了分离关注点的好处。使用Spring,可以在启动Webapp时在Spring上下文中将conf值替换为PlaceholderPropertyConfigurer。在这种情况下,您无论如何都必须选择正确的配置,例如可以在构建时进行配置。

与替换构建时间相比,如果需要,在未压缩的Webapp中临时操纵值会更容易。当然,如果您进行了任何更改,都需要重新启动Webapp,并且手动更改不会在Webapp重新部署期间持续存在。Spring还限于Spring上下文,因此在web.xml中不起作用(但由于其局限性,无论如何都应避免在web.xml中包含变量)。

从预定义文件中读取本地conf

这种方法可能是最简单的设置方法:只需发明一个配置文件路径,例如$HOME/mywebapp/conf.properties,让您的webapp在启动时以某种方式读取它。

这样做的好处是,在构建/部署Web应用程序时,您不必关心conf。无论如何,您应该有一些合理的conf默认值,然后可以被本地conf覆盖。

在数据库中拥有conf

这是用于覆盖conf参数的最灵活的解决方案,但在某些情况下也会变得复杂。大多数情况下,在具有namevalue的表中使用conf应该有效。

当然,您不能在数据库表中配置JDBC连接url,但这对于简单的文本/数字conf是一个很好的解决方案,因为它在建立db连接后会影响webapp的操作。为了避免性能下降,请确保以某种方式缓存conf,以便对其进行频繁访问。

额外的做法

正如kgiannakakis指出的那样,它还有助于为您的应用设置某种类型的配置诊断页面。

这在很大程度上取决于Web应用程序服务器为您提供的选项。对于具有不同JDBC URL的JBoss,我们有多个环境,JNDI名称在所有服务器上都保持不变,只是本地实例上的配置发生了变化,因此从构建到构建都没有错。

我想简短的答案是,最佳实践是将配置外部化,并使用每个服务器的正确设置将适当的文件保留在适当的位置,然后让Web应用读取该配置。外部化和读取的确切性质将取决于特定的配置和应用程序服务器。

编辑:这些配置不存在作为战争的一部分(在我们的情况下是耳朵),因此不会被覆盖。

首先,将所有经常更改的配置设置放在一个位置。如果您需要同时设置JNDI,编辑数据库值和修改属性文件以完成配置,这确实很困难。选择最容易编辑且更容易验证所有设置是否正确的介质。我会说属性文件是最好的解决方案。您可以轻松地编辑它们,而只需要快速浏览它们就可以看到一切正常。如果选择属性文件,请仔细选择属性文件的标准位置,然后为路径分配环境变量。

如果您有一个简单的测试来验证所有设置是否正确,它也会有所帮助。例如,您可以拥有一个测试页面,该页面显示配置参数并执行一些基本测试,例如尝试连接到数据库或远程服务器。

我们所做的工作很好。

启动时,我们的程序会在硬编码路径中读取配置文件。可以说是:

/config/fun_prog/config.xml

每个程序都有不同的硬编码路径(FunProgram在fun_prog中,Super Server在sup_serv中,等等),因此我们不必担心它们之间会相互漫游。

我们创建的一个小的配置库将读取XML文件。XML文件包含数据库连接信息,通常是邮件服务器配置数据,向其发送通知的电子邮件地址,是否应在测试模式下运行,外部服务的URL等。

因此,当我们需要进行更改时,我们将复制配置文件,编辑所需内容,然后重新启动程序。由于我们具有标准的服务器设置,因此只需将这些文件复制到周围(以及必需的httpd.conf修补),就可以在任何服务器上部署任何程序。

这并不花哨,但效果很好。理解,添加新的配置选项,备份和编辑非常简单。在所有平台上都可以使用(unix很明显,Windows将以/开头的路径转换为c:\,因此也可以在其中进行编辑)。

我们的工作站基本上运行与服务器相同的软件,只是对该配置文件进行了一些更改。

Seam或Grails(从Rails借来的)中使用了所需示例的好例子默认情况下,有三个配置文件:prod,dev,test,但是如果需要,您可以定义更多。

在Seam中,项目构建由Ant文件完成。每个配置文件都定义了内容可以变化的每个文件,例如数据源,sql脚本或属性文件。

import-dev.sql
import-prod.sql
import-test.sql

当使用选定的配置文件运行ant文件时,将采用适当的文件,并且配置文件名称将从该文件名中被截断。

以下是可以放置在目标中的代码段

<copy tofile="${war.dir}/WEB-INF/classes/import.sql" 
      file="${basedir}/resources/import-${profile}.sql"/>

JDBC URL,驱动程序名称可以外部化为属性文件(当然,配置文件名称为后缀)

<filterset id="persistence">
     <filter token="transactionManagerLookupClass" value="${transactionManagerLookupClass}"/>

<copy tofile="${war.dir}/WEB-INF/classes/META-INF/persistence.xml" 
     file="${basedir}/resources/META-INF/persistence-${profile}.xml">
     <filterset refid="persistence"/>
</copy>

或您可以从命令行传递给ant build调用的属性值。这是一个简短的示例,说明Seam已完成。

另一种选择是使用Maven通过maven方式,它可以通过属性和配置文件完成,但是您也可以使用单独的模块来拆分配置并创建具有主要功能的其他模块。Maven属性和配置文件的典型用例示例是针对多个数据库,部署服务器等的运行配置。当您要为不同的供应商创建配置时,甚至更困难,但是对于Maven来说,这不是问题:)

这个表单来自Carlos Sanchez博客,是使用Maven概要文件的一个很好的例子

总而言之,我强烈建议您查找Ant / Seam a Maven参数化文件(配置文件)。这些解决方案还有另一个优势:ant或maven脚本可以在CI服务器(如Hudson)中运行,并允许同时运行/测试所有配置文件。

您可以使用您选择的语言来使用组件配置模式

它在POSA书籍中有所描述(我认为在第4卷中)

(在Java中,您可以使用 commons-configuration 组件)。

有几种方法可以解决此问题:

  • 像您一样使用属性文件,但是添加“元属性”文件,该文件用于通过定义环境值(例如localhost主机名)到要加载的属性文件名之间的映射来选择所使用的属性文件。

  • 将您的属性放入数据库中,并将与应用程序服务器中的属性表的数据库连接定义为Web应用程序获取的资源。

  • 不要将属性文件放在.war或.ear中,而是创建一个properties-deployhost.jar存档,其中包含每个目标主机的属性文件。通过将适当的.jar文件添加到类路径,将其绑定到已部署的Web应用程序(例如,通过每个Web应用程序在应用程序服务器配置中的共享库)。

在部署时,只有其中的第一个不需要额外的手动步骤,而以在重命名目标系统时必须更新配置源和构建新的部署文件为代价。

我敢肯定,在这些方面有很多变体,您的方法也是可行的,最佳选择取决于您的情况。

请查看以下URL:http : //issues.apache.org/jira/browse/CONFIGURATION-394

我们正在寻找的Configuration框架是Apache Commons Configuration之上的东西,必须支持并发问题,JMX问题和大多数存储(例如.properties文件,.xml文件或PreferencesAPI)。

weblogic团队在“管理控制台”上提供的功能很有趣,您可以通过它在配置上进行事务性(原子性)更新,以便通知已注册的侦听器。

Apache的人坚持认为,这个项目可能不在Commons Configuration的范围之内!

我已经附上了一个简单的配置框架,请看看。

本文地址:http://java.askforanswer.com/java-webyingyongchengxupeizhimoshi.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!