Scala中的环境特定配置

Posted

技术标签:

【中文标题】Scala中的环境特定配置【英文标题】:specific config by environment in Scala 【发布时间】:2014-03-03 16:25:07 【问题描述】:

什么是在 Scala 中设置项目的好方法,该项目根据环境使用不同的配置。

我需要专门为开发测试生产环境设置不同的数据库(类似于Rails中所做的)

【问题讨论】:

【参考方案1】:

我使用的另一个策略是使用includes。 我通常将我的 DEV 设置存储在 default application.conf 文件中,然后为其他环境创建一个新的 conf 文件并包含默认文件。

假设我的 DEV conf application.conf 如下所示:

myapp 
    server-address = "localhost"
    server-port = 9000

    some-other-setting = "cool !"

那么对于 PROD,我可以有另一个名为 prod.conf 的文件:

include "application"

# override default (DEV) settings
myapp 
    server-address = $PROD_SERVER_HOSTNAME
    server-port = $PROD_SERVER_PORT

请注意,我覆盖了在 PROD 环境中更改的设置(some-other-setting 因此与 DEV 中的相同)。

配置引导代码不测试任何东西

...
val conf = ConfigFactory.load()
...

要从 DEV 切换到 PROD conf,只需传递一个带有要加载的配置文件名称的系统属性:

java -Dconfig.resource=prod.conf ...

在DEV中,不需要传递它,因为application.conf会被default加载。

所以这里我们使用Typesafe Config的默认加载机制来实现这一点。

我创建了一个简单的project 来演示这种技术。随意克隆和试验。

【讨论】:

为了完整起见,我相信配置引导程序将是: val conf = ConfigFactory.load() def apply() = conf.getConfig("myapp") @ozeebee 由于某种原因这不起作用。请注意,我在 build.sbt 中添加了:fork in run := truejava -Dconfig.resource=stg.conf。文件 stg.conf 在资源下,但我的配置仍然来自 application.conf。还要注意,当我使用:val conf = ConfigFactory.load("stg.conf") 时,我的配置会根据 stg.conf 加载。有什么想法吗? @has981 不知道。我设置了一个简单的project 来演示这种技术。随意克隆和实验。 @ozeebee 您的代码在本地运行良好,但是当我使用 Docker 和 Kubernetes 在 flink 上部署此代码时它无法运行 @Kallz 抱歉,我不知道 flink;也许这个工具有自己的配置机制?【参考方案2】:

使用类型安全配置。像这样创建一个 Config 对象:

import com.typesafe.config._

object Config 
  val env = if (System.getenv("SCALA_ENV") == null) "development" else System.getenv("SCALA_ENV")

  val conf = ConfigFactory.load()
  def apply() = conf.getConfig(env)

然后在src/main/resources文件夹中创建application.conf文件:

development 
  your_app 
    databaseUrl = "jdbc:mysql://localhost:3306/dev_db"
    databaseUser = "xxxx"
    databasePassword = "xxxx"
  

test 
  your_app 
    databaseUrl = "jdbc:mysql://localhost:3306/test_db"
    databaseUser = "xxxxx"
    databasePassword = "xxxx"
  

现在,您可以从应用程序的任何位置访问配置:

Config().getString("your_app.databaseUrl")

如果您在运行应用程序时设置了环境(例如export SCALA_ENV=test),它将考虑正确的配置部分。默认是开发

【讨论】:

我花了一段时间才找到这种保持系统属性首要地位的模式:ConfigFactory.defaultOverrides().withFallback(config2.getConfig(environment)).withFallback(config2); github.com/typesafehub/config/blob/master/examples/java/…【参考方案3】:

我对 Daniel Cukiers 解决方案不允许默认值和覆盖的方式不满意,因此我对其进行了更改以充分利用它们。

您需要做的唯一配置是在系统上设置一个 ENVIRONMENT 变量(如果未设置,则默认为“dev”)

(Java方案,兼容Scala):

import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;

public class MyCompanyConfig 
    public final static Config base = ConfigFactory.load().getConfig("mycompany");
    public final static String environment = System.getenv("ENVIRONMENT") == null ? "dev" : System.getenv("ENVIRONMENT");

    /**
     * Returns a subtree of the base configuration with environment settings applied.
     *
     * @param setting The subtree to return config for.
     * @return A config with base in given setting, with environment modifications applied.
     */
    public static Config load(String setting) 

        Config config = base.getConfig(setting);

        if (config.hasPath(environment)) 
            return config.getConfig(environment).withFallback(config);
        

        return config;
    

这允许库中的单个 reference.conf 如下所示:

mycompany.module1 
    setting1 : "adefaultvalue"
    url : "localhost"

    test 
        // will be used where ENVIRONMENT="test"
        url : "test.mycompany.com"
    

    prod 
        // will be used where ENVIRONMENT="prod"
        setting1 : "changethedefault"
        url : "www.mycompany.com"
    

用法:

Config conf = MyCompanyConfig.load("module1")

【讨论】:

以上是关于Scala中的环境特定配置的主要内容,如果未能解决你的问题,请参考以下文章

假期学习配置Scala环境(Ubuntu)以及配套Scala编程实验

关于scala环境配置详解

Scala详细环境安装与配置

scala安装教程及简单配置

Eclipse 配置scala开发环境(windows)

Scala概述与开发环境配置