Ruby on Rails多生产环境设置

3

我们如何使用不同的数据库配置运行Ruby on Rails应用程序?

详细地说,我想在生产环境下运行多个Rails应用程序实例,并为每个实例使用不同的数据库配置。这有可能吗?

4个回答

3

我认为你可以将database.yml中的配置复制到不同的环境中,例如prod1、prod2等,然后在启动每个相应的服务器之前设置RAILS_ENV环境变量以匹配...


同样对于config/environments/production.rb,只需将其重命名为prod1.rb、prod2.rb等。如果您使用capistrano进行部署,则可能需要在cap deploy命令行上指定-Srails_env=myenvironmentname - riffraff
或者对于Capistrano部署,可以查看ext包,因为它支持多个环境。唯一的问题是 - 它期望每个源树只有一个活动环境。如果您打算从同一源树激活多个环境,则可能需要进行一些调整。 - DGM
还有一集关于这个的Rails Cast。http://railscasts.com/episodes/72-adding-an-environment - rangalo

0
如果您能够控制和配置每个Rails实例,并且由于它们处于待机状态而可以承受浪费资源的情况,请节省一些麻烦,只需更改database.yml以修改每个实例使用的数据库连接。如果您关心性能,则此方法不可行。
对于绑定到仅一个数据库上的单个唯一表的模型,您可以在模型内部调用establish_connection:
establish_connection "database_name_#{RAILS_ENV}"

如此描述:http://apidock.com/rails/ActiveRecord/Base/establish_connection/class

你会有一些模型使用来自一个数据库的表格,而其他不同的模型使用来自其他数据库的表格。

如果你有相同的表格,在不同的数据库上是共用的,并且被单个模型共享,ActiveRecord 将无法帮助你。在 2009 年,我在一个项目中需要这样做,当时我使用的是 Rails 2.3.8。我为每个客户创建了一个数据库,并使用他们的 ID 命名了这些数据库。因此,我创建了一个方法来在 ApplicationController 中更改连接:

def change_database database_id = params[:company_id]
    return if database_id.blank?

    configuration = ActiveRecord::Base.connection.instance_eval { @config }.clone
    configuration[:database] = "database_name_#{database_id}_#{RAILS_ENV}"

    MultipleDatabaseModel.establish_connection configuration
end

并将该方法添加为所有控制器的 *before_filter*:

before_filter :change_database

对于每个控制器的每个操作,当params[:company_id]被定义和设置时,它将更改数据库为正确的数据库。

为了处理迁移,我扩展了ActiveRecord::Migration,并使用一个方法查找所有客户并迭代每个ID的块:

class ActiveRecord::Migration
    def self.using_databases *args
        configuration = ActiveRecord::Base.connection.instance_eval { @config }
        former_database = configuration[:database]

        companies = args.blank? ? Company.all : Company.find(args)

        companies.each do |company|
            configuration[:database] = "database_name_#{company[:id]}_#{RAILS_ENV}"
            ActiveRecord::Base.establish_connection configuration

            yield self
        end

        configuration[:database] = former_database
        ActiveRecord::Base.establish_connection configuration
    end
end

请注意,这样做将使您无法在同一操作中从两个不同的数据库进行查询。您可以再次调用*change_database*,但是当您尝试使用执行查询的方法时,来自不再链接到正确数据库的对象将变得混乱。此外,显然您将无法连接属于不同数据库的表。
为了正确处理此问题,应该大幅扩展ActiveRecord。现在应该有一个插件可帮助您解决此问题。快速研究给了我这个:
DB-Charmer: http://kovyrin.github.com/db-charmer/ 我愿意尝试它。让我知道哪个对您有效。

0

你可以像DGM提到的那样复制你的database.yml文件。然而,正确的做法是使用像Chef这样的配置管理解决方案。

如果你查看设置Rails堆栈的指南,它包括2个前端Web服务器+1个后端DB服务器。这将包括你复制database.yml文件的情况。


0

好的。我们需要在您的应用程序中创建多个环境

创建config/environmenmts/production1.rb,它将与config/environmenmts/production.rb相同

然后编辑database.yml以进行production1设置,完成后即可。

使用rails s -e production1启动服务器


-1,为了管理database.yml而创建额外的环境绝对不是推荐的做法。实际上这等同于硬编码。 - Swanand
在这种情况下,创建符号链接 production1,指向 production.rb ln -s production.rb production1.rb部署时也可以执行相同的操作。 - Sandip Ransing
显然,这就是楼主想要的。因此我会取消那个-1。 - Swanand

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