Getting information from one Rails server to Another

冷暖自知 提交于 2019-12-12 06:03:12

问题


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!


回答1:


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!



来源:https://stackoverflow.com/questions/31763634/getting-information-from-one-rails-server-to-another

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!