5

アップデート:

同じ問題がある場合は、前に「遅延したジョブが完了したことを ajax プロセスに通知する」をお読みください。ありがとうジーン


同時実行性に問題があります。いくつかの Web サイトをスクレイピングするコントローラーがありますが、コントローラーへの呼び出しごとに応答するのに約 4 ~ 5 秒かかります。

したがって、2 回 (またはそれ以上) 連続して呼び出すと、2 回目の呼び出しは最初の呼び出しを待ってから開始する必要があります。

では、コントローラーでこの問題を解決するにはどうすればよいですか? 多分EventMachineのようなもので?

更新と:

application_controller.rb

def func1
    i=0
    while i<=2
        puts "func1 at: #{Time.now}"
        sleep(2)
        i=i+1
    end
end

def func2
    j=0
    while j<=2
        puts "func2 at: #{Time.now}"
        sleep(1)
        j=j+1
    end
end

whatever_controller.rb

puts ">>>>>>>> Started At #{Time.now}"
  func1()
  func2()
puts "End at #{Time.now}"

したがって、同じユーザー/ブラウザ/などから同時にhttp://myawesome.app/whateverを数回要求する必要があります。

Unicorn で Heroku (およびローカル) を試しましたが、成功しませんでした。これが私のセットアップです。

要件:

  • RESTful ソリューションが必要です。これは API なので、JSON に応答する必要があります

詳細: 現在、2 つのクラウド サーバーを実行しています。

  • Heroku とユニコーン
  • Nginx + Panssenger を使用した Engineyard Cloud
4

5 に答える 5

2

応答時間が長いコントローラー関数の場合delayed jobgem は良い方法です。一括メール送信によく使用されますが、長時間実行されるタスクにも同様に機能します。

コントローラーは遅延ジョブを開始し、プレースホルダー (通常は進行状況インジケーター付きのグラフィック) と Ajax を含むページ、または利用可能な場合に完全な情報でページを更新する時間指定リロードで即座に応答します。これにアプローチする方法に関する情報は、この SO article にあります。

この記事では、メイン データベースではなく、redis またはその他のメモリ キャッシュを使用して結果を保存できることは言及されていません。

于 2014-02-26T10:13:20.927 に答える
2

上記の回答はソリューションの一部です。同時リクエストを別々のワーカーに適切にディスパッチできるサーバー環境が必要です。ユニコーンまたはパッセンジャーは、別々のプロセスまたはスレッドでワーカーを作成することにより、両方とも機能します。これにより、他の受信リクエストをブロックせずに、多くのワーカーが待機することができます。

他のソースからコンテンツを取得することが主な仕事である典型的なボットを構築している場合は、これらのソリューションで問題ない可能性があります。しかし、何百もの同時要求を受け入れることができる単純なコントローラーが必要であり、そのすべてが他のサーバーに独立した要求を送信している場合は、スレッドまたはプロセスを自分で管理する必要があります。あなたの目標は、単純な仕事をするために待機している多くのワーカーと、リクエストを送信することを仕事とする 1 つ以上のマスターを用意し、そこにいて応答を受け取ることです。Ruby の Thread クラスはシンプルで、このような場合に Ruby 2.x や 1.9.3 でうまく機能します。

より具体的な解決策にたどり着くために何をする必要があるかについて、より詳細な情報を提供する必要があります。

于 2014-02-26T05:52:54.687 に答える
1

どのルビーバージョンを利用していますか?

ルビーとウェブサーバー

ルビー

単純なアプリケーションの場合は、次をお勧めします。rubinius (rbx) や jruby の方が並行性に優れているため、それらを利用してみてください。主流の Ruby ではないという欠点がありますが、一部の拡張機能は動作しません。でも、シンプルなアプリなら問題ないです。

ウェブサーバー

セットアップする忍耐力がある場合は、Puma または Unicorn を使用してください

アプリが API サービスにアクセスしている場合

他のサイト(おそらくスクレイピングを許可するサイト)をスクレイピングしているときにグローバルロックがあなたを殺していることを示しています。この場合は、sidekiq や遅延ジョブなどを使用する必要がありますが、注意が必要です. これらはべき等ジョブになります。つまり、複数回実行される可能性があります。Web サイトに複数回アクセスし始めると、Web サイトのレート制限にすぐに到達します。Twitter では、1 時間あたり 150 件のリクエストに制限されています。そのため、バックグラウンド ジョブは慎重に使用してください。

あなたがデータを提供している場合

ただし、質問を読むと、コントローラーがAPIであり、ユーザーがそれを押すことによってロックが発生するように聞こえます。

この場合、dalli + memcached を使用してデータを提供する必要があります。memcached はメモリベースであるため、この方法では SQL ルックアップによって I/O が制限されることはありません。メモリ速度 > I/O速度

于 2014-02-27T01:23:46.080 に答える