从一台 Rails 服务器获取信息到另一台

Getting information from one Rails server to Another

我会尽量保持简短并公开讨论这个问题。

我有一个 Rails 应用程序,它是一个静态代码库,在 9 个不同的服务器上运行,所有这些服务器都具有相同的数据库模式,但当然具有不同的值。

我写了一些 SQL 来查询一些美元总额,并将把它放入 rake 任务或 sidekiq worker 中,让它每周触发一次以生成数据。最初我想的只是将每个服务器的结果数据扔到一个邮件程序中,然后将其邮寄给需要这些数据的人。这很简单。

但这有一个问题,我们需要在 highcharts 或其他图表引擎中查看随时间变化的指标。

所以这是我的想法。

  1. 创建 sidekiq worker 并按计划启动它
  2. 从每个服务器获取结果数据并通过 Postgres 将其填充到目标服务器上(不确定如何操作)
  3. 目标服务器将构建一个非常简单的 Rails 应用程序,在通过 postgres 填充数据后(以某种方式),该应用程序将具有一个模型,其中包含每个服务器(即服务器 1 服务器 2 等)的指标和关联) 从源服务器读取HighCharts中的数据并呈现视图

这就是我到目前为止的思考过程。当 sidekiq worker 启动时,我不确定如何通过实时 postgres 调用从源服务器获取数据。这就是问题#1。问题 #2 或更像问题 #2 是,这是否是在目标 Rails 服务器上创建某种消耗品 API 的更好用例?如果是这样,最好从哪里开始。

如果我的问题和思考过程不清楚,请告诉我,以便我更详细地澄清和解释。

干杯!

有很多关于如何在 Rails 中使用多个数据库连接以及如何在 Rails 中构建 API 的教程。几分钟的谷歌搜索将为您提供大量示例。但这里有一些准系统方法:

对于多个数据库连接,您是对的,您需要在 database.yml 文件中定义两个数据库的连接信息。示例:

# Local Database
development:
  adapter: mysql2
  database: local_db
  username: my_user
  password: my_password
  host: localhost
  port: 3306

# Reporting Database
development_reporting_db:
  adapter: postgresql
  encoding: unicode
  database: reporting
  username: some_user
  password: some_password
  host: 1.2.3.4
  port: 5432

Rails 不会对这个额外的块做任何事情,除非你明确告诉它。通常的做法是定义一个将建立第二个连接的抽象 ActiveRecord 模型:

class ReportingRecord < ActiveRecord::Base
  establish_connection( "#{Rails.env}_reporting_db".to_sym )
  self.abstract_class = true
end

然后,为位于报告数据库中并继承自 ReportingRecord 而不是 ActiveRecord::Base 的表创建新模型:

class SomeModel < ReportingRecord
  # this model sits on top of a table defined in database.yml --> development_reporting_db instead of database.yml --> development
end

要构建一个 API,有很多不同的方法可以做到。无论您采用何种方法,我都强烈建议您确保它只能通过 HTTPS 访问。这是一个基本控制器,其中包含一个响应 json 请求的操作:

class ApiController < ApplicationController
  before_filter :restrict_access # ensures the correct api token was passed (defined in config/secrets.yml)
  skip_before_action :verify_authenticity_token # not needed since we're using token restriction

  respond_to :json

  def my_endpoint_action
    render :json => {some_info: 'Hello World'}, :status => 200 # 200 = success
  end

  private
    rescue_from StandardError do |e|
      render :json => {:error => e.message}.to_json, :status => 400 # 400 = bad request
    end

    # ensures the correct api token was passed (defined in config/secrets.yml)
    def restrict_access
      authenticate_or_request_with_http_token do |token, options|
        token == Rails.application.secrets[:my_access_token]
      end
    end
end

此示例需要您在 config/secrets.yml 文件中定义访问令牌:

development:
  secret_key_base: # normal Rails secret key base
  my_api_access_token: # put a token here (you can generate one on the command like using rake secret)

在 API 和多数据库解决方案之间进行选择主要取决于您的应用程序将来可能如何扩展。多数据库方法通常更容易实现并且具有更高的性能。 API 倾向于更好地横向扩展,并且随着时间的推移,只有一个应用程序而不是 2 个或更多应用程序的连接的数据库往往更容易维护。

希望对您有所帮助!