Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 轨道&x2B;延迟作业:SSH连接池_Ruby On Rails_Ruby_Delayed Job_Net Ssh - Fatal编程技术网

Ruby on rails 轨道&x2B;延迟作业:SSH连接池

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分钟内完成。在这种情况下,每个任务都会打开单独的连接,这是无效的,有时由于连接太多而被目标服务器阻止

当前情况: 我有一个rails应用程序,有N个延迟工作的工人。每当我想向某台机器发送SSH请求时,我都会为工作进程创建一个任务。Worker执行以下操作:

Net:SSH.start(hostname, username, :password => pass) do |ssh|
  ssh.exec!(command)
end
有时我会创建50个这样的任务,一个接一个地执行,或者在5-10分钟内完成。在这种情况下,每个任务都会打开单独的连接,这是无效的,有时由于连接太多而被目标服务器阻止

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

ssh.exec!(command)
我所尝试的

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

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

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

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

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

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

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

    我个人只需要自己编写一个简单的线程化Ruby守护进程来处理这个任务。如果不想直接处理socket编程,可以使用类似的方法来处理通信和处理

    如果您对EventMachine或socket编程不满意,那么您可以查看一些消息传递系统,如,或 使用创建客户端和服务器

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

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

    如果您实现了这样的东西,请记住也要考虑安全因素。否则,您可以通过守护进程轻松地向任何人提供对所有远程计算机的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种其他可能的解决方案。