Ruby on rails 轨道&x2B;延迟作业:SSH连接池
当前情况: 我有一个rails应用程序,有N个延迟工作的工人。每当我想向某台机器发送SSH请求时,我都会为工作进程创建一个任务。Worker执行以下操作:Ruby on rails 轨道&x2B;延迟作业:SSH连接池,ruby-on-rails,ruby,delayed-job,net-ssh,Ruby On Rails,Ruby,Delayed Job,Net Ssh,当前情况: 我有一个rails应用程序,有N个延迟工作的工人。每当我想向某台机器发送SSH请求时,我都会为工作进程创建一个任务。Worker执行以下操作: Net:SSH.start(hostname, username, :password => pass) do |ssh| ssh.exec!(command) end 有时我会创建50个这样的任务,一个接一个地执行,或者在5-10分钟内完成。在这种情况下,每个任务都会打开单独的连接,这是无效的,有时由于连接太多而被目标服务器阻止
Net:SSH.start(hostname, username, :password => pass) do |ssh|
ssh.exec!(command)
end
有时我会创建50个这样的任务,一个接一个地执行,或者在5-10分钟内完成。在这种情况下,每个任务都会打开单独的连接,这是无效的,有时由于连接太多而被目标服务器阻止
我想要的:已打开存储在某处的连接,并由每个工作人员重新使用。这样每个工作进程都会以某种方式获得连接,然后运行
ssh.exec!(command)
我所尝试的:
- 将连接存储在文件/数据库/缓存中似乎是不可能的,因为它们不可序列化
- 尝试使用初始化器下实例化全局变量的singleton类。但是,每个worker的类对象是不同的(后来发现全局变量不能作为选项)
有办法解决这个问题吗?还有其他想法吗?谢谢 首先是一些基础知识;一个SSH连接的核心是到远程机器的低级套接字连接。进程之间无法(轻松)共享套接字。因此,在多个进程上运行的东西不能共享同一个SSH连接 接下来,您需要知道当前设置中的哪些部分在单独的进程中运行。我们得到的是:
只需让一个守护进程定期从Rails应用程序的数据库表中读取命令。然后,这个守护进程可以根据它在这个“作业队列”表中找到的内容执行这些命令。这样,您根本不必处理套接字通信,缺点是此解决方案是轮询解决方案 您的任务是否保留了一段时间,或者您只是异步化了SSH任务?任务实际上并没有延迟,而是更像是排队。例如,有一个操作A,在此过程中执行了大量ssh命令,然后执行任务B(5-10分钟),然后执行任务C(再次执行ssh请求)。非常感谢,这非常有用!我曾想过要有一个单独的进程,但这可能会成为我的应用程序的瓶颈(因为目前有N个DJ工作人员发送N*X请求,现在只需一个进程即可处理)。然而,看起来我别无选择。无论如何,非常感谢!是的,我在一个单独的DB表中考虑了任务:)这将是对延迟工作机制的模拟,我基本上必须在其中写入“workers”。。看起来有点过头了,我guess@AndreySereda只要让守护进程为它需要执行的每个命令启动一个线程。您可以更进一步,通过启动1-N个进程(每个进程都有自己的一组SSH连接池),实现某种负载平衡。在这种情况下,RabbitMQ或ZeroMQ可能会提供更好的体系结构。在任何情况下,我认为你都应该能够让它工作,甚至可以通过一些额外的脑力劳动来扩展它:)对那些没有对延迟工作或负载平衡做过任何事情的人有什么建议吗?我的应用程序几乎在加载到另一台机器的每个页面上都使用ssh,并运行页面上显示的脚本。有没有办法让我不必产生这么多ssh连接?似乎在同一个连接上线程是在我的控制器中执行此操作的正确方法?@user2004922您可能想问一个新的SO问题。你的问题中缺少一些信息,因此很难回答。一般来说,解决方案与我上面回答的相同,但也可能完全不同。取决于你实际上在做什么。也许这会有所帮助:,但根据您正在做的事情,您还有10种其他可能的解决方案。