1

潜在的に多くのレコードが配列された配列があります。すべてのレコードは、サーバーによってRESTfulRecordsControllerに保存されます。現時点での私のソリューションは次のようになります。

def self.send! options = nil
  records = fetch_records
  records.each do |r|
    send_data!(r) ? records = records.delete_if{|rec| rec == r } : break
  end
  storage.save! records

  true
end

private

def self.send_data! record, options = nil
  begin
    response = Net::HTTP.Proxy(configuration.proxy_host, configuration.proxy_port).start(configuration.host, configuration.port) do |http|
      request = Net::HTTP::Post.new(request_path options)
      request.body = record.to_json
      http.request request
    end
    raise StandardError unless response.code == "200"
  rescue Exception => e
    return false
  end

  true
end

このソリューションの利点は、ConnectionError、ConnectionTimeout、またはServerErrorが発生した場合に、未送信のレコードがローカルに保存され、後で再度送信できることです。一致するコントローラーは、標準のRailsコントローラーです。

私の今の問題は、本番モードではこれが非常に遅いように見えることです。サーバーがボトルネックになっていない場合は、約4リクエスト/秒です。

ここで問題となるのは、HTTPクライアントを1回だけインスタンス化し、同じ接続を使用してすべてのレコードを送信することが役立つかどうかです。私はそれを実装するための解決策を見つけられませんでした。なぜなら、ここにあるコードのsave_or_storeの振る舞いが必要だからです。

別の解決策は、次々に行われるレコードを転送するのではなく、それらをグループ化し、レコードのグループを受け入れてそれらを格納する新しいコントローラーを作成することです。

したがって、この質問は、技術的な質問よりもアーキテクチャ的な質問に要約されます。いずれにせよ、HTTP接続を開いたままにして、その方法でソリューションを高速化できるかどうか疑問に思います。

何か案は?

よろしくフェリックス

4

2 に答える 2

2

EventMachine ベースの HTTP クライアントに切り替え、em-http-requestその Multi インターフェイスを使用して同時に複数のリクエストを送信すると、スループットが少し向上する可能性があります。

しかし、より優れた HTTP クライアントのメリットはごくわずかです。コントローラーから取得した HTTP 応答で何もしないため (つまり、HTTP をアプリケーション プロトコルとして使用していないことを意味します)、問題の最善の解決策は、サーバー側で処理するために配列全体を実際に送信することです。 . 結局のところ、すべてのレコードに対して 1 つのリクエストを行うという代償を払う必要はありません。

最終的には、必要に応じて、処理に失敗したレコードのリストを含む URI を公開することをお勧めします。これにより、必要に応じて再送信するか、単に無視することができます。

そして、配列をシリアライズしてペイロードのサイズを縮小し、メッセージ交換を高速化するために、MessagePackをミックスに投入します。

于 2011-10-04T03:10:36.753 に答える
0

私が送信を読んでいる場合!メソッドを正しく実行すると、各レコードをループし、そのループ内で現在のレコードを配列から削除して、他のすべてを送信しますか?コンピューティング側の労力を少し節約するには、delete_ifの代わりにArrayクラスのdelete()メソッドを使用します。

def self.send! options = nil
  records = fetch_records
  records.each do |r|
    if send_data!(r)
      records.delete(r)
    else
      break
    end
  end
  storage.save! records

  true
end

send_dataのレコードパラメータをどこに渡すかはわかりませんが!方法。terinaryはそのメソッドの結果を使用するためです。

Net httpは、すべてのリクエストを実行するのに時間がかかる場合があります。応答コードを確認するために数百のURLを実行したとき、完了するまでに5〜10分かかりました。自分ではあまり使用していませんが、https ://github.com/jnunemaker/httpartyをご覧ください。多分それはあなたのためによりよく働くでしょう。

于 2011-09-29T12:08:33.220 に答える