【问题标题】:Rails + Delayed jobs: SSH connections poolRails + 延迟作业:SSH 连接池
【发布时间】:2014-01-01 17:15:05
【问题描述】:

现状: 我有一个带有 N 个延迟工作人员的 Rails 应用程序。每当我想向某台机器发送 SSH 请求时,我都会为工作人员创建一个任务。 Worker 执行如下操作:

Net:SSH.start(hostname, username, :password => pass) do |ssh|
  ssh.exec!(command)
end

有时我会创建例如50 个这样的任务要一个一个地执行,或者在 5-10 分钟内完成。在这种情况下,每个任务都打开单独的连接,这并不有效,有时会因为连接太多而被目标服务器阻塞。

我想要什么:已打开的连接存储在某处并被每个工作人员重用。这样每个工人都以某种方式获得连接,然后运行

ssh.exec!(command)

我的尝试

  • 在文件/数据库/缓存中存储连接似乎是不可能的,因为它们不可序列化
  • 已尝试将单例类与在初始化程序下实例化的全局变量一起使用。但是每个worker的类对象是不同的(后来发现不能选择全局变量)。

有没有办法解决这个问题?还有其他想法吗?谢谢!!

【问题讨论】:

  • 您的任务是保留了一段时间,还是只是在同步 SSH 任务?
  • 任务实际上并没有延迟,而更像是排队。例如,有一个操作 A,在此期间执行一堆 ssh 命令,然后是任务 B(5-10 分钟),然后是任务 C(再次 ssh 请求)

标签: ruby-on-rails ruby delayed-job net-ssh


【解决方案1】:

首先是一些基础知识;一个 SSH 连接的核心是与远程机器的低级套接字连接。套接字不能(轻松)在进程之间共享。因此,在多个进程上运行的东西不能共享同一个 SSH 连接。

接下来,您需要知道当前设置中的哪些部分在单独的进程中运行。我们得到的是:

  1. Rails 在大多数情况下是基于进程的:单独的 Web 请求在单独的进程上运行。因此,将 SSH 连接存储在 Rails 应用中并不是一个可靠的解决方案。

  2. 据我所知,延迟作业也是基于流程的。主进程启动从进程来处理每个作业。因此 DJ 也不适用于此目的。

您需要一个主进程来存储 SSH 会话,然后等待传入消息,这些消息是需要在远程 SSH 机器上执行的命令。

就我个人而言,我会自己编写一个简单的线程化 Ruby 守护进程来处理这个任务。如果您不想直接处理套接字编程,可以使用EventMachine 之类的东西来处理通信和处理。

如果您对 EventMachine 或套接字编程不满意,那么您可以查看一些消息传递系统,例如 RabbitMQ,或者 ZeroMQ 用于创建您的客户端和服务器。

我还为 Rails 找到了一个名为 ActiveMessaging 的东西,尽管我不确定该项目的最新情况和工作情况。

但就像我说的,我认为最简单的实现只是一个套接字守护进程,它在后台运行并跟踪打开的 SSH 连接,然后侦听来自 Rails 应用程序的命令。

如果您实施这样的事情,请记住还要考虑安全因素。否则,您可以通过您的守护进程轻松地让任何人通过 SSH 访问您的所有远程计算机。

编辑

一个更简单的想法:

只需让一个守护进程定期从 Rails 应用程序的数据库表中读取命令。然后这个守护进程可以根据它在这个“作业队列”表中找到的内容来执行这些命令。这样,您根本不必处理套接字通信,缺点是该解决方案是轮询解决方案。

【讨论】:

  • 非常感谢,这非常非常有用!我曾想过有一个单独的进程,但这可能会成为我的应用程序的瓶颈(因为目前有 N DJ 工作人员发送 N*X 请求,现在只由 1 个进程处理)。然而,看起来我别无选择。无论如何,非常感谢!
  • 是的,我考虑过在单独的数据库表中执行任务 :) 这将是延迟工作机制的模拟,我基本上必须向它写入“工人”.. 这看起来有点我猜是开销
  • @AndreySereda 让守护进程为它需要执行的每个命令启动一个线程。您可以更进一步,通过启动 1-N 个进程来实现某种负载平衡,每个进程都有自己的一组 SSH 连接池。在这种情况下,RabbitMQ 或 ZeroMQ 可能会提供更好的架构来使用。无论如何,我认为您应该能够使其工作,甚至通过一些额外的脑力劳动来扩大规模:)
  • 对没有对延迟工作人员或负载平衡做过任何事情的人有什么建议吗?我的应用程序在几乎每个页面加载到另一台机器上并运行页面上显示的脚本时都在 ssh'ing。有什么办法可以让我不必产生这么多的 ssh 连接?似乎在同一连接上进行线程处理是在我的控制器中执行此操作的正确方法?
  • @user2004922 你可能想问一个新的 SO 问题。您的问题中缺少一些信息,因此很难回答。一般来说,解决方案与我上面回答的相同,但也可能完全不同。取决于你实际在做什么。也许这会有所帮助:lysator.liu.se/fsh/fsh.html,但您还有 10 种其他可能的解决方案,具体取决于您正在做什么。
猜你喜欢
  • 1970-01-01
  • 2013-11-26
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2012-04-20
  • 1970-01-01
  • 2023-04-08
  • 2021-04-19
相关资源
最近更新 更多