特定于环境的配置文件 - 最佳实践?

时间:2023-01-12 23:26:19

I have an application with a configuration file which has a lots of environment-specific settings. Also I have a bunch of environments where that application can be deployed.

我有一个配置文件的应用程序,它具有许多特定于环境的设置。此外,我有一堆可以部署该应用程序的环境。

What are the best practices of making that configuration environment-specific?

使配置环境特定的最佳实践是什么?

Currently I'm adding the directory where the config files are located to the JVM classpath. This way application simply loads the configuration files from the classpath and uses what it finds there.

目前我正在将配置文件所在的目录添加到JVM类路径中。这样,应用程序只需从类路径加载配置文件,并使用它在那里找到的内容。

However, recently I was told that this is a bad practice and that I should consider using JNDI for such purpose.

然而,最近我被告知这是一种不好的做法,我应该考虑将JNDI用于此目的。

So, what could you recommend to make the deployment and development processes as painless as possible in my situation?

那么,您可以建议在我的情况下尽可能轻松地使部署和开发过程变得轻松吗?

Thanks in advance.

提前致谢。

5 个解决方案

#1


1  

You could allow users to specify the configuration file/directory with whichever of the following appeals to you: (1) a command-line argument; (2) a Java system property; or (3) an environment variable.

您可以允许用户指定配置文件/目录,其中包含以下任何一个内容:(1)命令行参数; (2)Java系统属性;或(3)环境变量。

Note that you can access the FOO_CONFIG environment variable by calling System.getenv("FOO_CONFIG"). Sun "deprecated" (a euphemism for deliberately broke) this operation between Java 1.0.1 and Java 1.4.x inclusive. However, this operation was undeprecated (that is, fixed) in Java 5.

请注意,您可以通过调用System.getenv(“FOO_CONFIG”)来访问FOO_CONFIG环境变量。 Sun“弃用”(故意破坏的委婉说法)Java 1.0.1和Java 1.4.x之间的这种操作包括在内。但是,此操作在Java 5中未被完善(即已修复)。

#2


1  

You could set up and maintain specific sets of config files per each environment, in distinct folders under your project root. Then you could extend your build process with a parameter to determine which environment to build for, so that it can copy the required config files into the package to deploy. The deployed app then sees the config files always in the same place, and it has only one consistent set of files, minimizing the chance of errors.

您可以在项目根目录下的不同文件夹中为每个环境设置和维护特定的配置文件集。然后,您可以使用参数扩展构建过程,以确定要构建的环境,以便它可以将所需的配置文件复制到要部署的包中。然后,部署的应用程序将配置文件始终放在同一位置,并且它只有一组一致的文件,从而最大限度地减少了出错的可能性。

The drawback of this approach is potentially lots of duplication between your config sets. This can be solved by generating the concrete config files as part of the build process. Extract all variable config parameters into distinct config property files, one per each environment, and create a template config file set, which contains placeholder names instead if the real parameters in every applicable place. Then all you need is a preprocessor in your build which creates a set of config files from the temples, replacing the placeholders with the corresponding concrete values. (E.g. Maven has built-in support for properties and profiles, and also for generating resources at build time.)

这种方法的缺点是您的配置集之间可能存在大量重复。这可以通过生成具体配置文件作为构建过程的一部分来解决。将所有变量配置参数提取到不同的配置属性文件中,每个环境一个,并创建模板配置文件集,如果每个适用位置都有真实参数,则包含占位符名称。然后,您需要的只是构建中的预处理器,它从镜像中创建一组配置文件,用相应的具体值替换占位符。 (例如,Maven内置了对属性和配置文件的支持,也用于在构建时生成资源。)

#3


1  

We have similar requirement. This is how we implemented it.

我们有类似的要求。这就是我们实施它的方式。

We have shared-app.war file that is shared accross different departments. The code in this .war file looks for (or reads from) shared-app-cfg.properties file. This properties file will be different for each department.

我们有不同部门共享的shared-app.war文件。此.war文件中的代码查找(或读取)shared-app-cfg.properties文件。每个部门的此属性文件都不同。

In .war file's manifest we say it depends on shared-app-cfg.jar.
The .war expects shared-app-cfg.jar to be available in runtime environment.
The contents of this .jar file is shared-app-cfg.properties.

在.war文件的清单中我们说它取决于shared-app-cfg.jar。 .war期望shared-app-cfg.jar在运行时环境中可用。此.jar文件的内容是shared-app-cfg.properties。

Each department will have to build this jar file containing properties file.
Depending on how each department builds their application they can:

每个部门都必须构建包含属性文件的jar文件。根据每个部门构建应用程序的方式,他们可以:

  1. Package shared-app-cfg.jar with shared-app.war file in an .ear file.

    将shared-app-cfg.jar与.ear文件中的shared-app.war文件打包。

  2. Alternatively, put the .jar file in shared-lib.
    Not sure if this is elegant solution... but it solves the issue.

    或者,将.jar文件放在shared-lib中。不确定这是否是优雅的解决方案......但它解决了这个问题。

#4


0  

IMHO, if you have lot of environment-specific information, you're better off using config files as you already do, had you had only a few strings, you could have used jndi environment strings instead.

恕我直言,如果你有很多环境特定的信息,你最好使用配置文件,如果你只有几个字符串,你可以使用jndi环境字符串。

#5


0  

Another guess (awaiting comments) - is it good practice to put "/configs" string into JNDI and let application load the configs from there? Looks better than adding it to classpath and still fulfills it's purpose pretty well. What do you think?

另一个猜测(等待评论) - 将“/ configs”字符串放入JNDI并让应用程序从那里加载配置是一种好习惯吗?看起来比将它添加到类路径更好,并且仍然很好地实现了它的目的。你怎么看?

#1


1  

You could allow users to specify the configuration file/directory with whichever of the following appeals to you: (1) a command-line argument; (2) a Java system property; or (3) an environment variable.

您可以允许用户指定配置文件/目录,其中包含以下任何一个内容:(1)命令行参数; (2)Java系统属性;或(3)环境变量。

Note that you can access the FOO_CONFIG environment variable by calling System.getenv("FOO_CONFIG"). Sun "deprecated" (a euphemism for deliberately broke) this operation between Java 1.0.1 and Java 1.4.x inclusive. However, this operation was undeprecated (that is, fixed) in Java 5.

请注意,您可以通过调用System.getenv(“FOO_CONFIG”)来访问FOO_CONFIG环境变量。 Sun“弃用”(故意破坏的委婉说法)Java 1.0.1和Java 1.4.x之间的这种操作包括在内。但是,此操作在Java 5中未被完善(即已修复)。

#2


1  

You could set up and maintain specific sets of config files per each environment, in distinct folders under your project root. Then you could extend your build process with a parameter to determine which environment to build for, so that it can copy the required config files into the package to deploy. The deployed app then sees the config files always in the same place, and it has only one consistent set of files, minimizing the chance of errors.

您可以在项目根目录下的不同文件夹中为每个环境设置和维护特定的配置文件集。然后,您可以使用参数扩展构建过程,以确定要构建的环境,以便它可以将所需的配置文件复制到要部署的包中。然后,部署的应用程序将配置文件始终放在同一位置,并且它只有一组一致的文件,从而最大限度地减少了出错的可能性。

The drawback of this approach is potentially lots of duplication between your config sets. This can be solved by generating the concrete config files as part of the build process. Extract all variable config parameters into distinct config property files, one per each environment, and create a template config file set, which contains placeholder names instead if the real parameters in every applicable place. Then all you need is a preprocessor in your build which creates a set of config files from the temples, replacing the placeholders with the corresponding concrete values. (E.g. Maven has built-in support for properties and profiles, and also for generating resources at build time.)

这种方法的缺点是您的配置集之间可能存在大量重复。这可以通过生成具体配置文件作为构建过程的一部分来解决。将所有变量配置参数提取到不同的配置属性文件中,每个环境一个,并创建模板配置文件集,如果每个适用位置都有真实参数,则包含占位符名称。然后,您需要的只是构建中的预处理器,它从镜像中创建一组配置文件,用相应的具体值替换占位符。 (例如,Maven内置了对属性和配置文件的支持,也用于在构建时生成资源。)

#3


1  

We have similar requirement. This is how we implemented it.

我们有类似的要求。这就是我们实施它的方式。

We have shared-app.war file that is shared accross different departments. The code in this .war file looks for (or reads from) shared-app-cfg.properties file. This properties file will be different for each department.

我们有不同部门共享的shared-app.war文件。此.war文件中的代码查找(或读取)shared-app-cfg.properties文件。每个部门的此属性文件都不同。

In .war file's manifest we say it depends on shared-app-cfg.jar.
The .war expects shared-app-cfg.jar to be available in runtime environment.
The contents of this .jar file is shared-app-cfg.properties.

在.war文件的清单中我们说它取决于shared-app-cfg.jar。 .war期望shared-app-cfg.jar在运行时环境中可用。此.jar文件的内容是shared-app-cfg.properties。

Each department will have to build this jar file containing properties file.
Depending on how each department builds their application they can:

每个部门都必须构建包含属性文件的jar文件。根据每个部门构建应用程序的方式,他们可以:

  1. Package shared-app-cfg.jar with shared-app.war file in an .ear file.

    将shared-app-cfg.jar与.ear文件中的shared-app.war文件打包。

  2. Alternatively, put the .jar file in shared-lib.
    Not sure if this is elegant solution... but it solves the issue.

    或者,将.jar文件放在shared-lib中。不确定这是否是优雅的解决方案......但它解决了这个问题。

#4


0  

IMHO, if you have lot of environment-specific information, you're better off using config files as you already do, had you had only a few strings, you could have used jndi environment strings instead.

恕我直言,如果你有很多环境特定的信息,你最好使用配置文件,如果你只有几个字符串,你可以使用jndi环境字符串。

#5


0  

Another guess (awaiting comments) - is it good practice to put "/configs" string into JNDI and let application load the configs from there? Looks better than adding it to classpath and still fulfills it's purpose pretty well. What do you think?

另一个猜测(等待评论) - 将“/ configs”字符串放入JNDI并让应用程序从那里加载配置是一种好习惯吗?看起来比将它添加到类路径更好,并且仍然很好地实现了它的目的。你怎么看?