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

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

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

【问题讨论】:

    标签: scala configuration environment-variables config development-environment


    【解决方案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),它将考虑正确的配置部分。默认是开发

    【讨论】:

    【解决方案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")
    

    【讨论】:

      猜你喜欢
      • 2013-08-16
      • 2014-04-25
      • 1970-01-01
      • 2020-08-02
      • 2017-12-08
      • 1970-01-01
      • 2014-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多