【问题标题】:Getting information from one Rails server to Another从一个 Rails 服务器获取信息到另一个
【发布时间】:2015-08-01 16:16:49
【问题描述】:

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

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

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

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

这是我的想法。

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

到目前为止,这就是我的思考过程。当 sidekiq 工作人员触发时,我不确定如何通过实时 postgres 调用从源服务器获取数据。这就是问题#1。问题 #2 或更类似于问题 #2 是,这是否是在目标 Rails 服务器上创建某种消耗性 API 的更好用例?如果是这样,最好的起点是什么。

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

干杯!

【问题讨论】:

  • 所以你有 9 个 Rails 应用程序实例在 9 个不同的服务器上运行,每个服务器都有自己的数据库?我会假设你有理由需要这种分离。如果我没看错,您是在询问通过 Rails/Sidekiq 从这 9 个数据库中聚合信息。您可以为这 9 个节点编写一个 api 端点,并让您的报告应用程序根据需要查询它们。或者...(字符不足,请参阅下一条评论)...
  • 您可以将 9 个节点设置为具有双数据库连接(1 个用于本地,1 个用于共享报告数据库)。所有节点都可以写入报告数据库,然后您的报告应用程序将拥有可用于构建您需要的任何类型报告的聚合信息。这两种方法都运作良好,并且各有优缺点。
  • @SeanHuber 实际上是的,分离是有充分理由的,因为出于安全/合规目的,必须将每个客户客户端服务器隔离。所以数据集是相同的,但具有不同的值。我在想,在 9 服务器上编写一个简单的 API 端点,允许对这个特定数据/功能的获取请求可能是最好的,然后将该数据拉入报告应用程序。我是 API 新手,所以你对如何开始编写 API 有什么建议吗?这将是我的第一个真正的 API。
  • @SeanHuber 也可以设置双数据库连接,最好的方法是什么?我以前从未这样做过,所以这对我来说是新的。我假设它是我可以为目标应用服务器设置的 database.yml 中的某些内容,它只会根据我在每个源服务器上创建的 AR 对象远程更新表?还是我走远了?感谢您的友好和有用的建议。 :)

标签: ruby-on-rails postgresql ruby-on-rails-4 highcharts rails-api


【解决方案1】:

有很多关于如何在 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 个或更多应用程序建立连接的数据库随着时间的推移往往更容易维护。

希望这会有所帮助!

【讨论】:

  • 这太棒了。在您回答之前,我已经进行了一些谷歌搜索并提出了很棒的教程,但是您的示例确实有助于缩小我的范围和重点。非常感谢您抽出宝贵时间回答我的问题。 :)
  • 这对 API 很有意义。然后在报告服务器上,我可以使用 HTTParty 或一些 RestClient 来查询每个服务器上的 API 并提取我需要的数据。 :) 很棒的酱汁。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多