【问题标题】:JavaEE solution configuration best practicesJavaEE 解决方案配置最佳实践
【发布时间】:2011-12-31 03:49:28
【问题描述】:

我们构建 3 层企业解决方案,通常由几个 webapp 和 ejbjar 模块组成,这些模块都与​​数据库通信并具有多个外部集成点。

每个模块通常都需要自己的配置,这些配置可以在解决方案的整个生命周期内发生变化。 部署它变成了一场噩梦,因为现在我们有 18 个属性文件,必须记住要复制和配置,还要设置数据源、队列、内存要求等。

我对有更好的方法充满希望但并不乐观。 我们考虑过/使用过的一些选项,各有优缺点:

  1. 使用多个 maven 项目和持续集成(例如 hudson 或 jenkins)构建一个配置 jar,其中包含每个环境(dev、qa、prod)的所有属性文件,然后将所有内容捆绑为一个 EAR。但是,在需要时无法在生产中轻易更改。
  2. 将大部分设置放在数据库中,并有一个简单的屏幕来修改它。在内部,我们可以拥有一个可以读取和修改值的通用配置服务 EJB。每个模块都可以有一个自定义扩展版本,其中包含特定的 getter 和 setter。
  3. 版本控制所有属性文件,然后在生产环境中将其签出,并在进行更改后将其签入生产分支。

有了所有这些,您仍然需要以容器特定的方式配置数据源和队列等:(

【问题讨论】:

    标签: java jakarta-ee jboss glassfish apache-tomee


    【解决方案1】:

    用户一个简单的数据库表(Section、Key、Value)。如果需要,请添加“版本”,并将整个内容包装在一个简单的 ConfigurationService 类中,并使用 getInt(String section, String key) 等方法

    工作量不大,它使应用程序代码非常整洁,并且非常容易调整配置。

    【讨论】:

    • 它会将配置更改转换为数据库更改。我目前雇主的应用程序就是这样做的。这不好玩。我们在环境之间复制数据库,并且必须对设置进行特殊处理。我们在开发中为不同的目的构建不同的数据库,并且必须硬塞进去。如果你想改变一些东西,你不能调整文件并重新启动,你必须点击数据库。我以前使用过基于文件的不错的设置,并且更喜欢它们。
    • @TomAnderson - 解释为什么更改数据库行比更改文件更复杂。而不是“在环境之间替换数据库”,您必须“在环境之间复制配置文件”。无论如何,我们不要把它变成真正的讨论(如果你愿意,可以继续在 Chat 上讨论),只是说它们在本质上非常相似,而且我发现 DB 更容易用于大型配置。
    • 这是一个更好的讨论场所,因为讨论是供后代阅读的。无论如何,我并不是说这种方法不好,对不起;只是它有其自身的复杂性。
    • 在复制时,在我们的例子中,无论如何我们都会复制数据库,因为我们需要生产数据的副本来进行测试。但是我们需要从中排除配置表,因为这需要根据环境进行设置。这是一个烦恼。如果我要进行本地调整以测试某些东西,并且我刷新了我的数据库,我必须进入并再次将我的调整到位。根本问题是数据和配置的生命周期需要不同,将它们放在同一个存储中会迫使它们相同。
    • 在编辑时,我发现更改数据库比更改文件更难,因为我只能通过运行 SQL 命令来做到这一点。我可以在我的 IDE 中编辑文件,执行查找和替换、sed、grep 等操作。我可以复制文件以进行备份、更改,然后恢复备份。我可以有两组文件,并在它们之间交换以比较它们的效果。也许如果我有更好的数据库工具,我不会发现有这样的差异。
    【解决方案2】:
    1. 考虑将自定义配置对象绑定到JNDI。然后在您的应用程序中查找此对象以配置它们。好处 - 您可以使用自定义配置对象,而不是相当通用的 MapProperties
    2. 另一种方法是使用JMX 来配置您需要的应​​用程序。好处 - 您可以将必须​​配置的对象直接绑定到MBean Server,然后使用jconsolevisualvm 等知名工具来配置应用程序的组件。

    这两种方式都支持在运行时动态重新配置应用程序。我更喜欢使用JMX

    【讨论】:

      【解决方案3】:

      我已经经历了几个循环来寻找方法来做到这一点。我还没有确定的答案。

      最后一个循环以基于属性文件的进程结束。这个想法是每个服务器实例都配置有一个配置所有内容的属性文件。该文件由启动脚本、应用服务器和应用程序本身读取以设置内存参数。

      不过,关键是这个文件不是直接管理的。相反,它是构建过程的产物。我们有一系列用于不同目的的文件,保存在版本控制中,以及一个合并适当文件的构建步骤。这使您可以分解出沿各个轴共享的共性。

      例如,我们有开发、持续集成、QA、UAT、暂存和生产环境,每个环境都有自己的数据库。不同环境中的服务器需要不同的数据库设置,但给定环境中的每台服务器使用相同的设置。因此,有类似 development-db.properties、qa-db.properties 等。在每种环境中,我们都有几种服务器——Web 服务器、内容管理服务器、批处理服务器等。每种服务器都有 JVM 设置、堆大小等,这些设置与其他类型的服务器不同,但在跨服务器之间保持一致环境。所以,我们有类似 web-jvm.properties、cms-jvm.properties、batch-jvm.properties 等等。我们还有一种方法可以覆盖特定系统 - production-cms-jvm.properties 之类的东西。我们还有一个 common.properties 来设置通用属性,以及可以在需要时覆盖的合理默认值。

      我们的构建过程实际上比从每个集合中选择正确的选项要复杂一些;我们为每个环境中的每个服务器都有一个主文件,它指定了要包含的其他文件。我们允许文件指定要包含的其他文件,因此我们可以构建导入图以最大限度地重用。

      它最终变得相当复杂。太复杂了,我觉得。但它确实奏效了,而且它确实让以受控方式影响许多服务器的更改变得非常非常容易。我们甚至合并了一组来自开发的输入文件和另一个来自运营的输入文件,其中包含敏感信息。这是一种非常灵活的方法。

      【讨论】:

        【解决方案4】:

        有趣的替代配置文件格式:编写一个 scala trait。然后,您的配置文件可以只是一个 scala 文件,您可以在服务器启动时编译和评估该文件。 http://robey.lag.net//2012/03/26/why-config.html

        【讨论】:

          【解决方案5】:

          我知道这已经得到了回答,我的回答不一定是通用的,但这是我的看法:

          注意,这里我只考虑系统/资源属性,而不是应用程序设置。在我看来,应用程序设置(例如支付阈值或其他设置应该存储在数据库中,以便可以重新配置系统而无需重新启动服务或通过重新部署或重新读取属性文件导致停机) .

          对于影响系统不同部分如何相互连接的设置(例如 Web 服务端点等),我会使用 JNDI 树。

          然后将使用 Websphere 控制台设置数据库连接和 JMS 连接,并且可以由 Websphere 管理员进行管理。这些也可以创建为 JACL 脚本,如有必要,可以将其放入版本控制中。

          除了 JNDI 资源之外,对于其他属性,例如用于 Web 服务调用后端的用户名等,我会使用 Websphere“名称空间绑定”。这些绑定可以使用 Websphere 控制台进行编辑,并通过 JNDI 使用“cell/persistent/mypassword”名称进行访问。

          所以我可以创建“mypassword”绑定(一个字符串),它的管理由 Websphere 管理员负责(远离开发人员的眼睛或其他不应访问生产系统的人),而同一个 EAR 文件可用于开发、测试、预生产和生产(最好为不同的系统提供不同的 EAR 文件,因为降低了其他差异潜入的可能性)。

          然后,Java 代码将使用简单的 JNDI 查找(并可能将值缓存在内存中)。

          相对于属性文件的优势:

          • 没有需要保护的“易受攻击”文件,因为系统属性包含密码。
          • 不必添加 Java 安全策略来允许访问该文件位置

          相对于数据库属性的优势:

          • 不依赖于将一个数据库绑定到应用服务器。

          希望有帮助

          【讨论】:

            【解决方案6】:

            使用多个 maven 项目和持续集成(例如 hudson 或 jenkins) 来构建一个包含所有属性的配置 jar 每个环境(dev、qa、prod)的文件,然后捆绑所有内容 作为EAR。但是在生产中事情不能轻易改变 需要时。

            我认为配置应该在应用程序实例的数据库中。您的本地机器配置可能与 dev 和 QA、PROD、DR 等不同。

            您需要一种以简单的方式将配置从数据库中取出的方法。

            我使用提供的 Apache commons-configuration 依赖项创建了一个单独的项目 它有多种存储数据的方式,但我喜欢数据库,并且配置存在于数据库环境中。

                import javax.sql.DataSource;
                import org.apache.commons.configuration.DatabaseConfiguration;
            
                public class MYConfig extends DatabaseConfiguration {
            
                    public MYConfig(DataSource datasource) {
                        super(datasource, "TABLE_CONFIG", "PROP_KEY", "PROP_VALUE");
                    }
                }
            

            将大部分设置放在数据库中,并有一个简单的屏幕可以修改 它。在内部,我们可以有一个通用的配置服务 EJB,它 可以读取和修改值。每个模块可以有一个自定义扩展 具有特定 getter 和 setter 的版本。

            Commons 配置作为一个简单的 API,然后您可以根据需要编写 GUI。 您可以按照自己的意愿制作界面。或者作为速赢没有界面。

            版本控制所有属性文件,然后在生产中检查它 并在进行更改后将其签入生产分支。

            版本控制很棒。使用组合添加另一个 DatabaseConfiguration。您扩展的类是活动配置,组合类是审计。还有另一个构造函数可以有一个版本。只需重载正确的方法即可获得所需的效果。

                import javax.sql.DataSource;
                import org.apache.commons.configuration.DatabaseConfiguration;
            
                public class MYConfig extends DatabaseConfiguration {
                    final DatabaseConfiguration audit;
            
                    public MYConfig(DataSource datasource) {
                        super(datasource, "TABLE_CONFIG", "PROP_KEY", "PROP_VALUE");
            
                        audit = new DatabaseConfiguration("TABLE_CONFIG_AUDIT", "PROP_KEY", "PROP_VALUE");
                    }
                    @Override
                    public void addProperty(String key, Object value) {
                        Object wasValue = super.getProperty(key);
                        super.addProperty(key, value); 
                        audit.put(key,wasValue);//add version code
                    }
                }
            

            http://commons.apache.org/proper/commons-configuration/

            【讨论】:

              猜你喜欢
              • 2011-04-08
              • 1970-01-01
              • 1970-01-01
              • 2011-06-11
              • 1970-01-01
              • 2015-04-24
              • 1970-01-01
              • 2012-02-23
              • 2016-01-08
              相关资源
              最近更新 更多