从一个Rails服务器获取信息到另一个 [英] Getting information from one Rails server to Another

查看:101
本文介绍了从一个Rails服务器获取信息到另一个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



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

我编写了一些SQL来查询一些美元总计,并将它放入一个rake任务或一个sidekiq工作人员,每周一次生成数据。最初我只是想将每台服务器产生的数据放入邮件发送器中,然后邮寄给需要数据的人员。这是非常简单的。



但是,这里有一个问题,我们需要看到在高层或其他图表引擎中随时间推移的指标。



所以这是我的想法。


  1. 创建sidekiq工作程序并按计划启动它

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

到目前为止,这是我的思考过程。我不确定如何在sidekiq工作人员触发时通过实时postgres调用从源服务器获取数据。所以这是问题#1。问题2或更多问题#2问题是,这是否是在目标Rails服务器上创建某种可用API的更好用例?如果是这样,最好的地方是开始。



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

干杯!

解决方案

有很多关于如何使用多个Rails中的数据库连接以及在Rails中构建API。几分钟的谷歌会给你很多的例子。但是这里有一些准系统的方法:

对于多个数据库连接,你是对的,你需要在<$ c中定义的两个数据库都有连接信息$ c> database.yml 文件。例子:

 #本地数据库
开发:
适配器:mysql2
数据库:local_db
用户名:my_user
密码:my_password
主机:localhost
端口:3306

#报告数据库
development_reporting_db:
适配器: postgresql
编码:unicode
数据库:报告
用户名:some_user
密码:some_password
主机:1.2.3.4
端口: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 
#此模型位于database.yml中定义的表的顶部 - > development_reporting_db代替database.yml - >开发
结束

为了构建一个API,有很多不同的方法来完成它。无论您采用何种方式,我都强烈建议您确保只能通过HTTPS访问。这里有一个基本的控制器,其中一个动作响应json请求:

  class ApiController< ApplicationController 
before_filter:restrict_access#确保传递了正确的api标记(在config / secrets.yml中定义)
skip_before_action:verify_authenticity_token#因为我们使用标记限制,所以不需要

respond_to:json

def my_endpoint_action
render:json => {some_info:'Hello World'},:status => 200#200 =成功
结束

私人
rescue_from StandardError do | e |
render:json => {:error => e.message} .to_json,:status => 400#400 =错误请求
结束

#确保传递了正确的api标记(在config / secrets.yml中定义)
def restrict_access
authenticate_or_request_with_http_token do | token ,选项|
token == Rails.application.secrets [:my_access_token]
end
end
end

这个例子需要你在 config / secrets.yml 文件中定义一个访问令牌:

 开发:
secret_key_base:#正常的Rails秘密密钥库
my_api_access_token:#在这里放置一个令牌(可以在命令中生成一个使用rake秘密)

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



希望这有助于!

I'll try to keep this as brief as possible and open the question to discussion.

I have a Rails app which is a static codebase and runs on 9 different servers all the same db schema but of course with different values.

I wrote some SQL to query some dollar totals and will be putting this into either a rake task or a sidekiq worker and have it fire once a week to generate the data. Initially I was thinking of just throwing the resulting data from each server into a mailer and mailing it to whoever needs the data. This is pretty straight forward.

But there's a kink in this, we need to see metrics over time in highcharts or some other charting engine.

So here's my thought.

  1. Create the sidekiq worker and fire it on a schedule
  2. Take the resulting data from each server and populate it on a target server via Postgres (not sure how to do this)
  3. The target server will have a very simple Rails app built that will have a model with metrics and an association for each server (ie server 1 server 2 etc), after populating the data via postgres (somehow) from the source servers, read the data in HighCharts and present the view

So that's my thought process so far. I'm not sure on how to get the data from the source servers via a live postgres call when the sidekiq worker fires. So that's problem #1. Problem #2 or more like question #2 is, would this be a better use case for creating some sort of consumable API on the target Rails server? If so, what's the best place to start.

If my question and thought process is unclear, please let me know so I can clarify and explain in better detail.

Cheers!

解决方案

There are plenty of tutorials on how to use multiple database connections in Rails as well as building an API in Rails. A few minutes of Googling will give you plenty of examples. But here are a couple barebones approaches:

For multiple database connections, you are right, you'll need to have the connection info for both databases defined in your database.yml file. Example:

# 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 won't do anything with this extra block though unless you explicitly tell it to. The common practice is to define an abstract ActiveRecord model that will establish the second connection:

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

Then, create new models for tables that reside in your reporting database and inherit from ReportingRecord instead of 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

For building an API, there are tons of different ways to do it. Regardless of your approach, I'd highly suggest you make sure it's only accessible via HTTPS. Here's a basic controller with one action that responds to json requests:

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

This example would require you to define an access token in your config/secrets.yml file:

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)

Choosing between an API and a multiple DB solution depends mostly on how your application might expand in the future. The multiple DB approach is typically easier to implement and has higher performance. An API tends to scale horizontally better and databases that have a connection from only one application instead of 2 or more tend to be easier to maintain over time.

Hope this helps!

这篇关于从一个Rails服务器获取信息到另一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆