什么是管理配置数据的最佳方法?

31

我正在开发一个包含四个产品的产品套件。目前,所有的配置数据都在XML或属性文件中。这种方法是不可维护的,因为我们需要为不同的环境(例如生产环境、开发环境等)管理不同的配置文件。

那么,最佳的处理配置数据的方式是什么呢?

另外,我们能否将其模块化成一个单独的模块?以便所有产品都可以使用该模块。 我们不想使用属性文件。我正在寻找一种解决方案,即将所有与配置有关的代码移动到一个新的配置模块中,并将所有配置数据保存在数据库中。


我不确定我理解关于模块的问题? - Nicole
1
我们不希望将配置数据保存在属性或XML文件中。我们想将这些数据集中存储在数据库中。因此,我考虑在我们的应用程序中创建一个单独的模块来处理所有配置相关的内容。 - Shekhar
2
据我所知,您已经决定不使用基于属性文件的方式,而您似乎有些事情没有告诉我们。您能否告诉我们为什么您更愿意让数据库维护配置文件呢?您仍然需要有某些外部的东西来管理与数据库连接所需的属性。 - Nicole
1
只需添加另一个看起来很棒的配置库:https://github.com/typesafehub/config - Asaf Mesika
9个回答

22

使用commons-configuration,您可以获得一个统一的API来访问属性,无论它们如何被表示——.properties、xml、JNDI等等。例如:

config.properties

jdbcHost=192.168.12.35
jdbcUsername=dbuser
jdbcPassword=pass

config.xml:

<config>
   <jdbcHost>192.168.12.35</jdbcHost>
   <jdbcUsername>dbuser</jdbcUsername>
   <jdbcPassword>pass</jdbcPassword>
</config>

在这两种情况下,它们可以通过类似以下方式访问:

String host = config.getString("jdbcHost");

10
我不确定,但我觉得这并没有回答楼主的问题。楼主似乎知道如何从XML或属性文件中检索值,但是在维护多组配置文件方面遇到了问题。 - Nicole
在他的更新之后,它变得更加清晰了。起初并不是这样。而且,commons-configuration有助于维护多个配置文件集合。 - Bozho

12

您已接近成功...我建议您保持相同的方法,并通过类似以下任一方法之一,为运行的应用程序实例拉入正确的配置文件:

  1. 将所有配置文件命名不同,并根据某些唯一标准(用户名、主机名等)拉入应用程序中:

    • production.properties
    • developer1.properties
    • developer2.properties
  2. 将它们保留在代码库之外的位置,该位置基于应用程序假定存在的环境变量:

    • YOURAPP_CONFIG_DIR/server_config.xml
    • YOURAPP_CONFIG_DIR/database_config.properties

我甚至在同一个项目中使用了这些方法的组合(对于构建过程配置使用 #1,对于运行时配置使用#2)。


对于第一种方法,您建议将配置文件放在Maven项目中还是不应该将配置放在同一个代码存储库中? - tuk

5
如果您的应用程序需要与数据库协作,您可以按照以下方式创建一个“配置”表:
create table configuration (mode char(3), key varchar(255), value varchar(1023));

您可以使用一个初始化脚本来初始化它,比如说init.sql文件,其内容大致如下:
insert into configuration values ('pro', 'param1', 'value1'); -- production
insert into configuration values ('dev', 'param1', 'value1'); -- development
insert into configuration values ('tst', 'param1', 'value1'); -- testing
...

这种方法的好处如下:
  • 您可以将脚本与代码一起版本化
  • 通过添加用户/组ID,可以轻松扩展它以包括每个用户或每个组的设置
  • 如果需要,您可以在运行时更改设置
  • 您可以使用与处理核心应用程序数据相同的堆栈(JPA + DAO,Cayenne等)来处理配置数据

9
你是如何读取连接数据库的配置参数的? :-) - PhiLho
为什么硬编码,当然是因为这样更方便!说正经的,拥有一个“引导”配置文件来存储数据库访问信息是可以的,只要数据库用于存储其他配置并获得上述好处。 - Tomislav Nakic-Alfirevic

4

对于我们所有的环境,配置数据以属性文件的形式存在于目标机器上。我们使用SpringFramework的 PropertyPlaceholderConfigurer将这些属性绑定到我们的应用程序中,以使跨环境移植性更强。

例如,只要我知道无论我的应用程序在哪台机器上运行,都会有 /etc/myapp/database.properties 文件存在,那么在我的 Spring 配置中,我只需要像这样编写:

    <bean id="myPropertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>/etc/myapp/database.properties</value>
        </list>
    </property>
</bean>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url"
        value="jdbc:mysql://${db.host}:3306/${db.name}" />
    <property name="username" value="${db.user}" />
    <property name="password" value="${db.pass}" />     
</bean>

关于Spring课程中属性文件存放位置的选择有很多选项。你甚至可以将它们作为替换项,并将其作为环境变量传递:

    <bean id="myPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="searchSystemEnvironment" value="true" />
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
    <property name="locations">
        <list>
            <value>${database.configuration.file.url}</value>
        </list>
    </property>
</bean>

在bash_profile(或其他文件)中: export JAVA_OPTS="-Ddatabase.configuration.file.url=file:///etc/myapp/database.properties"
或者,根据您的操作,只需在调用“java”时传递相同的-D选项。
顺便说一句,我们将属性文件作为RPM包单独维护。

2

有很多不同的策略。它们都很好,取决于哪种最适合您。

  1. 构建单个工件并将配置部署到单独的位置。该工件可以具有占位符变量,在部署时,可以读取配置文件。查看Spring属性占位符。对于使用Spring的Web应用程序,它非常出色,不涉及运维。
  2. 有一个外部化的属性配置,存储在Web应用程序之外。保持位置恒定,并始终从属性配置中读取。随时更新配置,重新启动即可使用新值。
  3. 如果要修改环境(即使用的应用程序服务器或用户/组权限),请考虑使用上述方法和puppet或chef。还可以使用这些工具管理配置文件。

0
在这些日子里,只有在应用程序启动期间传递配置是合理的方式。不要将配置作为构建过程的一部分!
根据12因素应用程序,配置应该作为环境变量传递。不应该有任何实际环境绑定的配置文件。即名为"dev"、"local-john-pc"的配置文件是错误的。"moreLogs"、"logToFile"这样的配置文件是可以的。所有其他内容(与数据库的连接参数、用户名等)应该在启动过程中作为环境变量传递。

0

2023年的现代解决方案:

你最好的选择是创建一个Spring Boot Java应用程序,并在application.propertiesapplication.yml文件中定义所有属性。

优点:

  • 使用属性或YAML来管理所有内容非常简单。包括数据库相关内容、日志、服务器端口等。
  • 在代码中定义属性,非常方便。
  • 不再因为不知道在哪里定义了什么而感到困惑。

0

环境变量是最简单的方法之一。像设置其他变量一样设置它们,使用System.getenv("...")访问它们。


0

Config 是一款配置文件管理工具。您可以创建适用于所有环境的通用配置,也可以创建特定于某个环境的配置。您可以继续使用 XML 和属性文件,并让 Config 维护环境之间的差异。您可以将 Config 视为集中式数据库,它可以以您想要的格式输出配置文件。每当您需要配置文件时,只需从 Config 部署(推送或拉取)到所需位置即可。请注意,我是 Config 团队的一员。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接