7

背景:
第 1 步 -> 我们有一个盒子,它通过在具有特定配置的测试模式下运行应用程序来运行应用程序的单元和功能测试。
第 2 步 -> 第 1 步成功后,我们通过在另一个框中以不同配置集在测试模式下运行应用程序来运行应用程序的集成测试。
第 3 步 -> 第 2 步成功后,我们通过在性能测试框中以生产模式运行应用程序来运行应用程序的性能测试。
第 4 步 -> 第 3 步成功后,构建被认为是稳定的,并且 UAT 框会使用该代码库进行更新,并且应用程序在生产模式下运行,以供客户审查和反馈。第 5 步 -> 使用客户的 GO,使用代码库更新生产框。

现在,从上述步骤我们观察到,在步骤 1 和 2 中,当应用程序在测试模式下运行时,它具有不同的配置。步骤 3,4 和 5 的情况类似。

在这种情况下,推荐的做法是什么?我们有 YAML 配置文件,但我个人觉得维护大量配置文件没有意义。于是,我从
“每个环境的配置文件”
的做法变成 了
“每个rails模式的配置文件,将变量外部化到linux环境”的做法。

我在正确的轨道上吗?我的行动难道不是简化事情吗?

这两种方法的优缺点是什么?

4

3 回答 3

12

根据我的经验,环境变量是最后的配置选项。它们绝对有自己的位置,但应用程序通常应该首先检查一些其他更可靠和明确有意的配置选项。我强烈建议从 YAML 文件加载配置,并且只使用环境变量作为后备。始终假设您的环境变量将应用于系统范围内的所有内容,并假设它会在某些时候意外地被取消设置或设置为错误的值。即,您的应用程序不应提交 seppuku,因为某些配置目录已设置为/并且它没有权限(或者更糟糕的是,您擦除驱动器,因为应用程序运行为root)。或者更有可能,像你这样的东西RAILS_ENV被设置为test当它应该是production并且没有人意识到时,现在用户正在将数据写入错误的位置或/dev/null由于所有 500 个帐户。

就个人而言,我喜欢在logger.warn回退到配置值的环境变量时删除消息。

老实说,对于您的确切问题,我可能会在命令行上传递要启动哪个环境的配置值。

于 2011-01-12T23:25:26.470 回答
0

经过大量谷歌搜索,与一些 Rails 人员讨论和头脑风暴后,我对代码进行了更改,以便我有“每个 Rails 模式的配置文件,将应用程序配置外部化为 YML 文件,在我的情况下仍然存在在 Rails 环境之外”

按照不言自明的代码片段来了解我如何以简单的方式实现它。快速解释是 environment.rb 文件中的代码片段从系统读取 YAML 文件,以将所有键值对复制到 Rails 的 ENV 哈希。此 ENV 散列在应用程序加载时/打开/之后随处可用。

File: config/environment.rb
# Mechanism to load all application related configurations
$CONFIG_FILE = "/var/myapp/config/jsconfig.yml"
require 'yaml'
APP_CONFIG = YAML.load_file($CONFIG_FILE)
APP_CONFIG.each do |key, value|
  ENV[key] = value
end

#3rd Party Server's (that my application is using) Configurations here...
3RD_PARTY_SERVER_URL = ENV['3rd_party_webservice_endpoint_url']
3RD_PARTY_SERVER_CREDENTIALS = {:username => ENV['3rd_party_server_username'], :password=> ENV['3rd_party_server_password']}


File: /var/myapp/config/jsconfig.yml
3rd_party_webservice_endpoint_url: url
3rd_party_server_username: username
3rd_party_server_password: password
myapp_db_url: jdbc:oracle:thin:@localhost:1521:XE
myapp_db_username: kartz
myapp_db_password: rails_savvy


File: /var/myapp/config/database.yml
development:
  adapter: oracle_enhanced
  url: <%= ENV['myapp_db_url'] %>
  username: <%= ENV['myapp_db_username'] %>
  password: <%= ENV['myapp_db_password'] %>
  encoding: utf8

test:
  adapter: oracle_enhanced
  url: <%= ENV['myapp_db_url'] %>
  username: <%= ENV['myapp_db_username'] %>
  password: <%= ENV['myapp_db_password'] %>
  encoding: utf8

production:
  adapter: oracle_enhanced
  url: <%= ENV['myapp_db_url'] %>
  username: <%= ENV['myapp_db_username'] %>
  password: <%= ENV['myapp_db_password'] %>
  encoding: utf8

它的更多细节可以在我的博客文章中找到:https ://blog.codonomics.com/2011/02/externalizing-all-application-specific.html

于 2011-02-02T17:28:54.823 回答
0

在我的公司,在某种程度上,我们实际上两者都有。

我们有一个 Rails 应用程序,它可以指向另一个软件的许多不同安装中的一个,并使用该安装中的 API。要指定安装,需要设置大约 5 个变量。

我们将这些变量中的每一个都作为单独的环境变量,但是设置所有这些变量很快就会过时,我们不可避免地会忘记一个。

所以现在我们有一个环境变量,我们调用 ENV_TOKEN,我们有 yaml 文件,其中包含对应于有效 ENV_TOKEN 变量的条目,以及设置 ENV[key]=value 的 config/initializers 中的代码。

所以假设我有变量“FOO”和“BAR”,我想分别设置为“one”和“two”。我可以创建一个包含以下内容的 yaml 文件:

carolclarinet:
  FOO: one
  BAR: two

然后我将我的环境变量 ENV_TOKEN 设置为 carolclarinet,并将 FOO 和 BAR 设置为一和二。

我不知道这是否是最好的方法,但它对我们有用。

ETA:请注意,这仅用于开发和测试,我们软件的安装程序负责设置所有这些,因此我们的客户永远不会更改任何环境变量。

于 2011-01-12T22:11:28.303 回答