2013-12-13 20 views
5

現在の状況: 私は遅れている仕事の労働者N人のレールアプリを持っています。あるマシンにSSH要求を送信したいときはいつでも、私はその作業者のためのタスクを作成します。ワーカーは次のようなことを行います。Rails +遅延ジョブ:SSH接続プール

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

そのようなタスクを1つずつ、または5〜10分以内に50回実行する。この場合、各タスクは個別の接続を開きます。これは効果的ではなく、接続が多すぎるためにターゲットサーバーによってブロックされることがあります。

私が欲しいもの:開いた接続をどこかに保存し、各作業者が再利用しました。ファイル/データベース/キャッシュ内の接続を格納

  • は、彼らが
  • 直列化可能でないとして可能ではないことになります。各ワーカーは、何とかしてから接続を取得しているので、ちょうど私がを試してみました何

    ssh.exec!(command) 
    

    を実行します

  • は、初期化子の下でインスタンス化されたグローバル変数を持つシングルトンクラスの使用を試みました。しかし、クラスオブジェクトはワーカーごとに異なります(後でグローバル変数をオプションにすることはできません)。

解決方法はありますか?他のアイデア?ありがとう!!

+0

あなたのタスクをしばらく保持しているのですか、SSHタスクをただ非同期化していますか? –

+0

タスクは実際には遅延されていませんが、キューに追加されたものです。たとえば、sshコマンドの束が実行され、次にタスクB(5-10分)、次にタスクC(再びssh要求)が実行される操作Aがあります。 –

答えて

3

最初にいくつかの基本事項。 1つのSSH接続は、その中心にリモートマシンへの低レベルソケット接続です。ソケットは、プロセス間で(簡単に)共有することはできません。したがって、複数のプロセスで動作するものは、同じSSH接続を共有することはできません。

次に、現在のセットアップのどの部分が別々のプロセスで実行されているかを知る必要があります。私たちが得るものは次のとおりです。

  1. ほとんどの場合、プロセスベースのWeb要求が別々のプロセスで実行されます。 SSH接続をRailsアプリケーションに保存することは、信頼できる解決策ではありません。

  2. 遅延ジョブは、私が知る限り、プロセスベースです。マスタープロセスは、各ジョブを処理するスレーブプロセスを起動します。したがって、DJもこの目的のためには動作しません。あなたが必要なもの

は、SSHセッション(複数可)を保存するマスター・プロセスであり、そして、あなたのリモートSSHマシンのいずれかで実行する必要のあるコマンドです着信メッセージを待機します。

個人的に私はこのタスクを処理する簡単なスレッドRubyデーモンプロセスをコードします。ソケットプログラミングを直接処理したくない場合は、EventMachineのようなものを使って通信と処理を処理することができます。

あなたがEventMachineまたはソケットプログラミングに慣れていない場合、その後、あなたがあなたのクライアントとサーバーを作成するRabbitMQ、または ZeroMQのようないくつかのメッセージングシステムで見ることができます。

また、私は現在のプロジェクトとその作業の仕組みがわからないが、ActiveMessagingと呼ばれるものも見つけました。

しかし、私が言ったように、最も単純な実装は、バックグラウンドで実行され、開いているSSH接続を追跡して、Railsアプリケーションからのコマンドを聞くソケットデーモンプロセスだと思います。

このようなものを実装する場合も、セキュリティ上の考慮事項を忘れないようにしてください。それ以外の場合は、デーモンプロセスを通じて、誰でも簡単にすべてのリモートマシンにアクセスできるようにすることができます。

EDIT

アンさらに簡単アイデア:

ちょうどデーモンプロセスが定期的にあなたのRailsアプリからデータベース・テーブルからコマンドを読みました。次に、このデーモンは、この「ジョブキュー」テーブルで検出されたものに基づいて、これらのコマンドを実行できます。この方法では、ソケット通信をまったく処理する必要はありませんが、このソリューションがポーリングソリューションであるという欠点があります。

+0

ありがとう、これは非常に便利です!私は別のプロセスを持つことを考えましたが、これは私のアプリケーションのボトルネックになる可能性があります。N個のDJワーカーが現在N * Xリクエストを送信しているので、ただ1つのプロセスで処理されます。しかし、私は他の選択肢がないように見えます。とにかく、ありがとう! –

+0

そして、はい、私は別のDBテーブルのタスクについて考えました:)これは、遅延ジョブメカニズムのシミュレーションとなるでしょう、私は基本的にそれに "労働者"を書く必要があります..私は少しオーバーヘッドを見て私は推測する –

+0

@AndreySeredaちょうどデーモンに、実行する必要のあるコマンドごとにスレッドを起動させます。さらに一歩進んで、それぞれ独自のSSH接続プールセットで1-Nプロセスを起動することで、何らかの負荷分散を実装できます。この場合、RabbitMQまたはZeroMQは、よりうまくいくアーキテクチャを提供するかもしれません。いずれにせよ、あなたはそれを働かせることができなければならないと思うし、余分な頭脳のビットでスケールすることもできるでしょう:) – Casper