我在看一个Rails应用程序将需要为背景,ActiveRecord的会话的一部分建立从Heroku的远程SSH会话(SSH隧道?)到远程MySQL数据库。 目标将是通过该通道进入该应用迁移在不同时间的数据。 通过网络连接到远程MySQL数据库不会是一个选项。
几个问题:
- Heroku上是否允许ssh方式连接了他们的迪诺?
- 什么是这样做的缺点?
- 我将不得不担心SSH会话持久性(工作可能需要1小时)?
- 最后,我怎么可以配置Rails和Heroku上启用一个database.yml的mysql的端点远程连接?
好了,我现在可以四处寻找了几天后,回答我的问题。 总之,是的。
class LegacyAccount < ActiveRecord::Base
self.table_name = "account"
def self.test_connection
# net-ssh-gateway gem
gateway = Net::SSH::Gateway.new("ip_address","ssh_user_name",
password: "password",
port: "port if different from 22",
verbose: :debug
)
port = gateway.open('127.0.0.1', 3306, 3307)
establish_connection :legacy_production
result = LegacyAccount.first
puts "Record: #{result.to_yaml}"
gateway.close(port)
gateway.shutdown!
result
end
end
并在您的database.yml:
legacy_production:
adapter: "mysql2"
host: "127.0.0.1"
username: "root"
password: "password"
database: "legacydb"
port: 3307
secure_auth: false
我试图@ user1322092的做法和陷入困境时,多个客户端试图访问该数据库,因为每个人会试图打开一个连接(除第一次会得到一个错误)。
我创建涉及的赛道产卵的SSH过程和使用的所有通信一个可怕的解决方案。 血淋淋的细节是https://stackoverflow.com/a/27361295/558639 。 除了是真的缺憾,但这样会导致延迟每次进程启动,您是否在访问远程数据库的时间。
更新
因此,这里的出现很好地工作更好的方法:只需陷阱(和忽略) Errno::EADDRINUSE
错误。 下面的代码:
require 'net/ssh/gateway'
class Mole
TUNNEL_HOST = <redacted>
TUNNEL_USER = <redacted>
AWS_HOST = <redacted>
TUNNEL_PORT_NUMBER = 3307
attr_reader :tunnel_gateway, :tunnel_port
# Call this to open an SSH tunnel from the current machine. If the
# the tunnel was already opened (e.g. by another process) , you'll
# get a warning message
def open_tunnel
@tunnel_gateway = Net::SSH::Gateway.new(TUNNEL_HOST, TUNNEL_USER)
begin
@tunnel_port = @tunnel_gateway.open(AWS_HOST, 3306, TUNNEL_PORT_NUMBER)
rescue Errno::EADDRINUSE => e
$stderr.puts("Warning: #{e.class}: #{e.message}")
end
end
# You won't normally call this, because the tunnel is a system wide
# resource; you don't know when other processes want to release it.
def close_tunnel
r = @tunnel_gateway.close(@tunnel_port) if @tunnel_gateway
@tunnel_gateway.shutdown!
r
end
end